演示项目架构
本项目以电商注册/购物场景,演示基于敏捷开发、微服务架构,在云原生环境下构建高性能、高并发、高可用、弹性伸缩互联网平台的主要技术。基础部分是4个基于SpringBoot
的Dubbo
微服务和1个Web
应用,另外还包括以下技术点:
1、Docker容器化
除PinPoint
外,Dubbo
服务、Web
应用以及所有中间件都支持Docker容器运行,项目包含Dockerfile
、构建Docker
镜像和运行Docker
容器的脚本,无需任何人工部署/配置即可快速运行整个演示应用。
2、Kubernetes
K8s
是一个优秀的容器自动化运维管理平台,简化了容器大规模部署和管理问题,结合Service Mesh
的路由、熔断和限流,微服务架构中的非功能性需求基本都被分拆出来,应用只需聚焦于业务逻辑。- 不可变基础设施、基础设施即代码,基于
Docker
、K8s
、DevOps
的云原生理念,是对运维管理的一场革命。 - 将研发团队持续集成、持续部署、持续交付能力提升一个台阶。
本项目为Mycat
+ ZipKin
运行演示应用提供了K8s
配置文件,可以快速部署到k8s
运行,参考Kubernetes运行演示应用。
关于K8s中部署Dubbo服务 \
Dubbo
服务的注册、发现、负载均衡、故障转移都采用Dubbo自己的机制,不使用K8s Service
。Provider
注册时通过Downward API
得到POD IP
,用POD IP
向Dubbo
注册中心注册,Consumer
从注册中心拿到Provider
的POD IP
,可以直接通讯。Dubbo
服务使用Deployment
部署到K8s
,无需建立K8s Service
,K8s
中基于Deployment
、ReplicaSet
的管理功能都能运用在Dubbo
服务上,包括手动扩缩容以及利用HPA自动扩缩容等。POD
下线、新POD
上线由Dubbo
本身的服务注册发现机制处理。
3、Service Mesh: Istio
目前Istio
无法管理Dubbo
流量,本项目演示了使用Istio
对shop-web
进行流量管理。
支付宝的SOFAMesh扩展了Istio
协议,增加了SOFARPC、Dubbo
协议支持,但该项目目前已经作废,直接向Istio
贡献,所以需要花时间等待Istio
接纳这些功能。
4、数据库分库分表
本项目演示了使用Mycat
和Sharding-Proxy
进行分库分表,相关概念、部署和使用方法,参考MyCat分库分表概览、Sharding-Proxy分库分表概览,以及它们与阿里云DRDS对比DRDS产品概览。
Mycat
、Sharding-Proxy
和DRDS
都实现了MySQL
协议,成为独立的中间件,将分库分表、读写分离等数据存储的弹性伸缩方案与应用隔离,对应用透明,并且实现语言无关。
5、分布式事务管理
Seata
是阿里云分布式事务管理GTS
的开源版,2019年1月开源,1.0.0
版已经发布。相关概念、部署和使用方法参考Seata分布式事务管理框架概览。
Seata
提供AT
、TCC
、Saga
三种柔性事务模式,可以跨微服务和应用实现分布式事务管理,AT
模式对应用几乎透明,使用方便,但目前还存在一些比较严重的问题:
- 性能开销还比较高;
- 在使用
Mycat
、Sharding-Proxy
进行分库分表时,Seata
会产生不少路由到全分片执行的SQL操作,详细参考Seata分布式事务管理框架概览文末;
6、APM全链路监控
演示项目支持PinPoint
、SkyWalking
、ZipKin
三种APM工具进行链路跟踪和性能分析,相关概念、部署和使用方法,参考PinPoint部署和使用、SkyWalking部署和使用、ZipKin部署和使用。三种APM工具对比:
- 使用方式:
PinPoint
和SkyWalking
都采用javaagent
方式,对应用代码几乎没有侵入性;ZipKin需要和应用打包到一起,并在应用中完成各种配置,属于强依赖关系; - 链路跟踪能力:整体上看相差不大,基本都参照Google Dapper,也都支持对大量主流框架的跟踪,细节上有些差异:
- 对单次RPC调用分析,
ZipKin
定义的Annotations更精细,参考ZipKin部署和使用; PinPoint
和SkyWalking
都提供将额外方法添加到调用链跟踪的功能,其中PinPoint
对代码完全没有侵入性,SkyWalking
则需要对方法添加注解;SkyWalking
支持在Span
中添加自定义tag功能,利用该功能可以将方法参数值等额外信息记录到Span
中,有利于问题分析;
- 对单次RPC调用分析,
- UI功能:
PinPoint
和SkyWalking
UI功能比较丰富,都提供应用/服务、实例等层级的性能统计,两者各有特色;ZipKin
UI功能最弱,只提供依赖关系、具体调用链查看分析;
额外的UI功能,可以读取APM工具的数据,自定义开发; - 社区支持:
ZipKin
架构灵活、文档完善,社区支持度最高,Spring Cloud
和Service Mesh
(istio)官方提供ZipKin
支持;SkyWalking
是华为员工开发,已成为Apache项目;PinPoint
为韩国公司开源;
云原生环境下K8s
、Istio
为监控、链路跟踪、日志等提供了统一的解决方案,其中ZipKin
和SkyWalking
支持Istio
。
7、自动化测试、验收测试
自动化测试、验收测试在敏捷开发、持续集成、持续部署中扮演了重要角色,本项目演示了Postman + Newman
进行接口自动化测试,Fitnesse
进行验收测试(服务接口)。
运行演示应用
演示应用支持本地运行、Docker
容器运行、K8s
运行、Istio
运行。另外,演示架构中用到的一些框架,例如MyCat
、ShardingProxy
、Seata
、ZipKin
、SkyWalking
、PinPoint
,都支持开关方式启用和禁用。
环境要求
- 操作系统
Linux
Windows
: 必须安装一个bash shell
,例如git bash
;Mac
:Mac
自带的sed
与GNU sed
不同,需要在Mac
上安装gnu-seed
:brew install gnu-sed
JDK8+
,Apache Maven
- 容器运行需要安装
Docker
,本地Docker Desktop
环境运行Kubernetes
、Istio
示例,为Docker Desktop
设置6G以上内存。在Mac上为
Docker Desktop
设置5GB内存运行Istio
示例时,曾导致Kubernetes
崩溃,内存改为6G后正常。
演示项目编译打包
./package.sh
为项目编译打包脚本,参数说明:
- 简单运行:不带任何参数执行
package.sh
,仅运行Dubbo微服务和演示应用,使用单个MySQL数据库、Nacos
注册中心,运行4个Dubbo
服务和1个Web应用; - 分库分表:
-mycat
、-sharding-proxy
二选一。-mycat
:使用Mycat
分库分表;-sharding-proxy
:使用Sharding-Proxy
分库分表;
- 分布式事务:
-seata
:使用Seata
分布式事务管理;
- APM全链路跟踪:
-zipkin
、-pinpoint
、-skywalking
三选一。-zipkin
:使用ZipKin
进行链路跟踪、性能分析;-pinpoint
:使用PinPoint
进行链路跟踪、性能分析;-skywalking
:使用SkyWalking
进行链路跟踪、性能分析;
例如./package.sh -mycat -seata -zipkin
本地运行演示应用
- 安装MySQL,建库建表。建库脚本docker/mysql/scripts/1-mydemo.sql,是演示分库分表用的建库脚本,简单方式运行只需要其中
mydemo-dn1
单库即可。 - 部署
nacos
,用于Dubbo
注册中心。参考Nacos快速开始即可。 - 如果要使用到某个中间件,例如
ShardingProxy
、PinPoint
,必须部署配置好。 - 修改项目配置。项目配置都在parent pom.xml中,包括数据库连接信息、
nacos
地址等。 - 编译打包。参考上一节编译打包。
- 按依赖关系依次启动
Dubbo
服务和Web应用:java -jar item-service\target\item-service-0.0.1-SNAPSHOT.jar java -jar stock-service\target\stock-service-0.0.1-SNAPSHOT.jar java -jar user-service\target\user-service-0.0.1-SNAPSHOT.jar java -jar order-service\target\order-service-0.0.1-SNAPSHOT.jar java -jar shop-web\target\shop-web-0.0.1-SNAPSHOT.jar
访问方式:
ShopWeb
:localhost:8090/shopNacos
:localhost:8848/nacos,登录用户/密码:nacos/nacosZipKin
:localhost:9411/zipkinSkyWalking
: localhost:8080Mycat
:数据端口8066
、管理端口9066
,都可以用MySQL
客户端登录访问ShardingProxy
:端口localhost:3307
,可以用MySQL
客户端登录访问
Docker容器运行演示应用
使用Docker
容器运行演示项目非常简单,基础组件无需自行部署、配置,直接运行容器即可。
由于PinPoint
只能采用HBase
存储,本项目未制作Dockerfile
,除PinPoint
外其它组件全部支持容器运行。
- 基础组件构建
Docker
镜像:docker/build-basis.sh
相关脚本和Dockerfile
在docker
目录中,每个基础组件一个子目录,其中build.sh
构建Docker
镜像,run.sh
启动运行Docker
容器,都不需要任何参数。 - 基础组件运行
Docker
容器:docker/deploy-basis.sh
最好根据需要修改deploy-basis.sh
,仅运行本次需要用到的组件。若手工启动,注意按依赖关系依次启动:mysql -> mycat/shardingproxy/nacos/zipkin/skywalking -> seata
。如果启用的组件比较多,例如同时启用
Mycat + Seata + SkyWalking + Nacos
,至少给Docker
分配5G以上内存,否则内存紧张可能导致容器和应用卡死。因为不少组件内存占用比较大,例如Seata
,JVM启动参数-XX:MaxDirectMemorySize
小于1G时一直报OOM异常。 - 为演示应用构建Docker镜像、运行
Docker
容器。- 参考
package.sh
,编译打包; - 使用
./docker/deploy-mydemo.sh
管理Docker
镜像和容器,其操作对象为所有Dubbo
服务和shop-web
应用,参数说明:-build
:构建Docker
镜像;-run
:运行Docker
容器;-stop
:停止Docker
容器;-rm
:删除Docker
容器(需要先停止Docker
容器);-rmi
:删除Docker
镜像(需要先删除Docker
容器);
- 参考
示例:
./docker/build-basis.sh # 为所有基础组件构建Docker镜像
./docker/deploy-basis.sh # 为所有基础组件运行Docker容器
./package.sh -mycat -seata -zipkin # 编译打包演示应用
./docker/deploy-mydemo.sh -build -run # 对演示应用构建Docker镜像、运行容器
./package.sh -shardingproxy -skywalking # 编译打包
./docker/deploy-mydemo.sh -stop -rm -rmi -build -run # 重新构建Docker镜像、运行容器
访问入口:
ShopWeb
:localhost:18090/shopNacos
:localhost:18848/nacos,登录用户/密码:nacos/nacosZipKin
:localhost:19411/zipkinSkyWalking
: localhost:18080Mycat
:数据端口localhost:18066
、管理端口localhost:19066
,都可以用MySQL
客户端登录访问ShardingProxy
:端口localhost:13307
,可以用MySQL
客户端登录访问MySQL
:13306
,可以用MySQL
客户端登录访问
Kubernetes运行演示应用
- 部署和启动
Kubernetes
环境。国内环境在Docker Desktop for Windows/Mac
中启用Kubernetes
,参考AliyunContainerService/k8s-for-docker-desktop。 - 参考Docker容器运行,为基础组件
MySQL
、Nacos
、Mycat
、ZipKin
构建Docker
镜像。 无需为演示应用构建Docker
镜像,在下面脚本中会自动重新打包应用,构建Docker
镜像。 - 执行
./k8s/deploy-k8s.sh
在K8s
中部署演示应用。
如果部署过程有错误,执行./k8s/undeploy-k8s.sh
可以将k8s
中已经部署好的部分全部删除。
访问入口:
ShopWeb
:localhost:30090/shopNacos
:localhost:30048/nacos,登录用户/密码:nacos/nacosZipKin
:localhost:30041/zipkinMycat
:数据端口30066
、管理端口30067
,都可以用MySQL客户端登录访问MySQL
:30006
,可以用MySQL客户端登录访问
备注说明:
- 简单起见,本演示项目采用
NodePort
方式向K8s
集群外部暴露端口,方便Docker Desktop
单机模式本地访问,可自行尝试Ingress
等其它K8s
方案。 - 基础组件多为有状态服务,不支持扩缩容(会数据不一致、错误等),另外未采用
PV
、PVC
等,POD
重启所有数据都会丢失。 - 所有
Dubbo
服务支持K8s
扩缩容(user-service
默认部署了2个POD
),可以尝试K8s
管理(在Docker Desktop
中shop-web
不支持扩容,因为使用了NodePort
):# 将user-service扩容到3个POD kubectl scale --replicas=3 -f deployment/svc-user-deployment.yaml # 扩容后可以开启3个窗口,监控user-service POD日志,查看负载均衡分配情况 # 1. 找出user-service的POD kubectl get pods | grep svc-user # 2. 监控每个POD中的容器日志(根据上面语句结果更换容器名称) kubectl logs svc-user-68ff844499-9zqf8 -c svc-user -f kubectl logs svc-user-68ff844499-dgsnx -c svc-user -f ...
Istio运行演示应用
- 需要在
Kubernetes
集群中部署Istio
,需要在istio-system
命名空间部署istio-ingressgateway
(Docker Desktop
默认部署和启动istio-ingressgateway
)。 - 在
default
命名空间开启自动注入:kubectl label ns default istio-injection=enabled --overwrite
。 - 参考Docker容器运行,为基础组件
MySQL
、Nacos
、Mycat
、ZipKin
构建Docker
镜像。 - 执行
./istio/deploy-istio.sh
在K8s
中部署演示应用。
如果部署过程有错误,执行./istio/undeploy-istio.sh
可以将k8s
中已经部署好的部分全部删除。 - 在本地
hosts
文件中绑定myshop.com
(Docker Desktop
绑定到本机IP即可)。
通过http://myshop.com/hello/YourName访问。
Dubbo
服务未使用Istio
进行流量管理,与Kubernetes
中部署方案相同(采用Dubbo
自己的服务注册发现机制)。
web-shop
部署了v1
、v2
两个版本,v1
2个POD
,v2
1个POD
,在URL中添加?version=v2
来访问v2
版本。可以分别对v1
、v2
版本进行扩缩容,查看访问效果。