我眼中的DUBBO
一. 前言
dubbo作为一款国内开源的优秀分布式服务框架,深受各互联网公司的喜爱,而且官方文档介绍非常详细,上手并不困难。因此,本文主要介绍dubbo在媒资系统中的应用,遇到的问题, dubbo源码学习的一些心得,详细使用流程请参见http://dubbo.io,如果有对dubbo感兴趣的开发者们可以申请加入https://github.com/dubbo 一同探讨,共同进步。
二. Dubbo是什么——what
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
以上概述是官网文档的解释,对于目前我的理解,what is dubbo?
dubbo是一款分布式服务框架
-高性能和透明化的RPC远程服务调用方案
-SOA服务治理方案
dubbo的基本架构图:(见微信)
进一步剖析,dubbo的基本原理如图2表示(见微信)
随着互联网应用的蓬勃发展,架构依赖越来越复杂,作为一款分布式服务框架,服务治理是dubbo最需要解决的问题。服务数量的激增,服务间依赖关系的复杂,以及服务调用量所带来的一系列问题,都是我们作为开发人员所要面临和解决的,这也是dubbo分布式服务框架形成的最重要原因。
三. 为什么使用Dubbo——why
1.首先介绍下Dubbo的一些主要特性。
一.透明化的远程方法调用
- 就像调用本地方法一样调用远程方法
- 只需简单配置,没有任何API侵入
二.软负载均衡及容错机制
- 可在内网替代nginx lvs等硬件负载均衡器
三.服务注册中心自动注册 & 配置管理
- 不需要写死服务提供者地址,注册中心基于接口名自动查询提供者ip
- 使用类似zookeeper等分布式协调服务作为服务注册中心,可以将绝大部分项目配置移入zookeeper集群
四.服务接口监控与治理
- dubbo-admin与dubbo-monitor提供了完善的服务接口管理与监控功能,针对不同应用的不同接口,可以进行多版本,多协议,多注册中心管理。
2.Dubbo在媒资系统中的应用。
透明化的远程方法调用
使用前,媒资系统内部服务调用主要通过数据库查询 和 HTTP接口方式实现。一则查询效率低,扩展一些搜索框架比较困难,二则解析http请求非常麻烦,不仅需要解析消息体,还有一些状态设置,使程序的复杂性大大提高。
对于一些复杂查询场景,like全表遍历查询效率低,因此我们引入了elasticsearch分布式搜索引擎,构建lucene倒排索引来弥补单纯依赖数据库查询功能的不足。基于ES构建mms-search作为服务提供者,将媒资不同类型数据的查询服务以dubbo-rpc远程调用的形式提供给数据消费方。提供方与消费方只需要简单配置(如图3),消费方就可以像调用本地方法一样远程调用接口。
(见微信)
服务接口监控与治理
其次搭建了一个zookeeper集群作为dubbo的注册中心,并搭建了一个修改过的dubbo-admin管理后台,(由于目前开源dubbo对于admin模块经过阉割,部分功能无法使用,需要修改部分源码来适应项目)如图4,5,6(见微信)
作为维护者,我们可以很容易得监控到目前所注册的所有接口的详细信息,并可以对每个接口进行及时处理。
配置管理
第三,我们扩展了dubbo-admin的功能,将zookeeper的配置管理功能与dubbo相结合,将原先配置在pom或者每个项目中的各种properties,xml等文件内容存入zookeeper节点,并通过dubbo-admin上传修改,大大简化了复杂系统的配置项,初期我们将此功能放入mms-webapps(媒资vrs后台)中操作,实践发现一旦mms-webapps出现了故障,整个mms系统都会因为缺少配置文件而崩溃,因此最终将配置管理功能移入dubbo-admin中,单独部署,不依赖其他mms模块,如图7,8(见微信)
3.后期优化与扩展
前期dubbo在媒资系统局部范围进行了实践,运行比较稳定。后期媒资内部服务治理,将全面RPC化;对外提供的媒资接口也会提供一套dubbo RPC 实现,方便JAVA系的消费方调用,实际看下dubbo在高并发应用场景下的表现。随着更大范围的推广使用,未来会更深入使用到dubbo更多的特性,如负载均衡,集群容错,服务降级,优雅停机,服务多版本,分组服务等。
四.Dubbo使用遇到的问题总结
1.目前dubbo在媒资系统运行良好,并没有出现很大的问题,有些开发者阅读完我们媒资系统的使用肯定会问,zookeeper担负着注册中心以及项目配置中心双重任务,如果挂了会怎样?目前我们的应对方案是3台zk服务做集群,leader选举的方式,并且在媒资监控模块中进行如下监控
节点自检 :
是指对集群中每个IP所在ZK节点上的PATH: /ZK.MONITOR.ALIVE.CHECK 定期进行三次如下流程 节点连接 - 数据发布 - 修改通知 - 获取数据 - 数据对比, 三次流程均成功视为该节点处于正常状态。(有兴趣具体zk可以查询下资料)
2.日志输出
dubbo默认使用log4j做日志输出,如果项目中使用的slf4j+logback,除了抛到外面的异常被自己的框架扑捉,dubbo本身的一些warn,info信息是没法记录的。
需要在xml中文件增加配置如下
<dubbo:application name="mms-webapp" logger="slf4j"/>
3.本地缓存注册中心
dubbo为了在不让请求每次都访问注册中心,同时在注册中心挂掉的时候仍然可以继续提供服务,会在本地把提供者的列表进行一个文件缓存。
默认不设置缓存文件地址会在当前用户根目录下创建文件夹.dubbo,缓存的注册中心文件会放在这里。
可以通过配置指定缓存文件的路径
<register file="/letv/dubbo.cache" />
但是这里一定要注意的是要保证启动app的用户要有这个目录下写文件的权限,否则会导致这个进程一直循环处理(dubbo内部实现是有异常cache,再次创建),cpu 100%)。
4.初期学习完成demo时需注意,如果将provider.xml与consumer.xml在一个工程中使用applicationContext.xml引入会报bean重复。模拟服务器启动要注意修改协议端口,每台服务器的协议端口也不相同,否则启动第二台服务器的时候就会报com.alibaba.dubbo.remoting.RemotingException: Failed to bind NettyServer错误
5. 出现RpcException: No provider available for remote service异常怎么办?
除了官方上的一些办法,我们在启动dubbo的时候如果遇到部分接口升级不希望注册时,可以使用
<dubbo:reference 标签> 配置check属性为false
这样dubbo就能正常启动了。