1. 引子
本文将结合运维便捷性要求容器部署(Tomcat)和DUBBO官方推荐Maven控制台工程做出分析对比以便更好地实施dubbo微服务架构。
2. DUBBO架构
使用dubbo来作为服务化中间件,dubbo作为一个RPC框架,大致的原理如下图:
- Registry:
注册中心;和服务的消费者,和服务提供者都建立长连接。服务提供者注册服务到注册中心;服务消费者从注册中心获取服务提供者列表; - Consumer: 服务消费端;服务消费者从注册中心获取到服务提供者列表后,根据负载均衡算法,选择一个服务提供者,和服务提供者直接建立连接,开始调用服务;
- Provider:服务提供者;服务提供者提供RPC服务;
- Monitor: 监控服务的调用情况统计;
- 注册中心为N+1对等集群,一台挂掉后,会自动切换到另外一台注册中心
- 注册中心全部挂掉后,消息消费者本地会缓存服务提供者列表,所以不影响当时的服务调用。
- 服务提供者为集群,一台挂掉后,通过心跳过程,注册中心会立即刷到服务消费者告知;
从以上架构可知,运维dubbo服务主要包含 DUBBO应用(APP) 监控中心(Monitor) 服务中心(Admin)管理三个方面,因此一下从三个方面分析对比选型。
3. DUBBO应用工程
总体来说,服务化工程类型分为两种standalong工程和web工程。
3.1 Standalong工程
- 工程结构
浅蓝色是目录,浅绿色是文件。assembly.xml(Maven打包配置,生成格式,包含文件等)不能修改,dubbo.properties和dubbo-provider.xml都可以修改,dubbo.properties描述服务公共配置,如注册中心,超时等;dubbo-provider.xml通过spring描述具体服务信息。
例子:
dubbo.properties
assembly.xml
- 部署结构
standalong型的应用启动停止都必须有对应的脚本,这些脚本文件不需要每个standalong型应用自己写,只需要工程结构遵循规范,执行mvn package/install后,会在target自动输出最后的部署包,部署包结构如下图:
浅蓝色是目录,浅绿色是文件。
lib目录:存放依赖的jar包,工程里java代码都会输出为jar包到lib里
start.sh:启动服务
restart.sh:重启服务
stop.sh:停止服务
server.sh:命令入口,如server.sh start
dump.sh:dump应用的线程栈,内存,GC;供排查问题用
3.2 web工程
web应用暴露服务,需要依赖web容器,这是不太标准的服务提供形式。
- 工程结构和部署结构
web应用的服务只需要配置在spring配置文件里,服务的启动停止依赖web容器的启动停止。
所以web工程的服务化不需要调整原有工程结构,只是要增加:api和impl。
因此web工程方式适合旧的非服务化程序的改造,影响较小。简单目录如下图:
4. DUBBO应用运行
4.1 Servlet容器运行
使用Servlet容器运行(Tomcat、Jetty等)—-不可取
不可取原因
1) 增加复杂性(端口、管理)
2) tomcat/jetty等占用端口,dubbo服务也需要端口
3) 浪费资源(内存):单独启动tomcat,jetty占用内存大
4.2 自建Main方法运行
自建Main方法类来运行(spring容器) —-不建议(本地调试可用)
不建议原因
1) Dubbo本身提供的高级特性没用上
2) 自己编写启动类,可能会有缺陷
4.3 框架的Main方法运行
使用Dubbo框架提供的Main方法类来运行(Spring容器)—-建议使用
建议原因
1) 框架本身提供(com.alibaba.dubbo.container.Main)
2) 可实现优雅关机(ShutdownHook)
注意点spring-context.xml
官方:服务容器的加载内容可以扩展,内置了spring, jetty, log4j等加载,可通过Container扩展点进行扩展。
4.4 优雅停机
摘抄官方说明如下(文档地址:http://dubbo.io/User+Guide-zh.htm
):
实现优雅停机的前提是,在启动时,需要指定参数-Ddubbo.shutdown.hook=true:
源码:
红框中显示,优雅关机的是循环关闭dubbo的container,因此实现dubbo优雅关机需要使用dubbo的container启动。
4.5 DUBBO容器
- 容器说明
再次摘抄官方文档:定义如下
Dubbo的容器模块,是一个独立的容器,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务。
服务容器只是一个简单的Main方法,并加载一个简单的Spring容器,用于暴露服务。
我们看启动生产者、消费者、简单监控者的 官方示例start.sh 命令中,可以看到启动命令如下:
nohup java
JAVAOPTS
JAVA_MEM_OPTS
JAVADEBUGOPTS
JAVA_JMX_OPTS -classpath
CONFDIR:
LIB_JARS com.alibaba.dubbo.container.Main > $STDOUT_FILE 2>&1 &
这里启动的就是 com.alibaba.dubbo.container.Main 类的 public static void (String[] args) { … } 方法。
- 容器启动
1) 如:(缺省只加载spring)
java com.alibaba.dubbo.container.Main
2) 或:(通过main函数参数传入要加载的容器)
java com.alibaba.dubbo.container.Main spring jetty log4j
3) 或:(通过JVM启动参数传入要加载的容器)
java com.alibaba.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j
4) 或:(通过classpath下的dubbo.properties配置传入要加载的容器)
dubbo.properties
dubbo.container=spring,jetty,log4j
不论生产者、消费者、简单监控 他们的启动 start.sh 命令都是完全一样的。 整个 bin 目录下的文件是完全一样的。
4.6 启动流程分析
以 dubbo-demo-provider-2.5.4-SNAPSHOT 为例,完整的启动加载过程如下图:
代码路径:
com.alibaba.dubbo.container.Main
com.alibaba.dubbo.container.spring. SpringContainer
5. Dubbo服务治理
目前仅有的选择为dubbo-admin,也符合服务开发人员使用习惯,缺点存在不少bug。
6. Dubbo服务监控
下表整理了目前业界提供的监控系统对比,详细如下表:
综上所述,本次采用dubbokeeper作为监控组件之一。部分页面如下:
7. 实践推荐
7.1 Standalong与Web并存
纯粹是后台服务工程采用Standalong方式,比如tradeCenter、paymentTool等。
Web服务提供Dubbo服务的使用Web方式,包括Boss-XXX。
7.2 Dubbo-Admin服务治理
7.3 Dubbo-Kepper服务监控
开源版本的dubbo-keeper作为服务监控工具,开源版本存在少量bug,需要修复。为了适应使用环境需要做适量改造。
7.4 其他
为了防止程序还没有完全启动结束即有客户端请求过来的问题,服务可配置延迟暴露。