Dubbo分布式治理

官方网站:apache dubbo Github: incubator-dubbo

许多公司采用 dubbo + spring boot + docker 的架构方式。

dubbo 是什么?

dubbo是一个分布式服务框架,提供高性能的以及透明化的RPC远程服务调用解决方案,以及SOA服务治理方案。

dubbo可以解决的问题(解决了不好治理的问题)

  1. url维护,订单系统会调用用户系统,用户系统也会调用订单系统,调用过多,url无法统一管理 解决方案:注册中心(zookeeper,redis,memcached..) 将对外暴露的服务url全部保存在第三方中间件上

  2. F5负载均衡压力较大,成本较高 解决方案:软负载均衡(zookeeper...)

  3. 服务架构依赖混乱,如果理出架构关系? 需要自动整理架构关系的方式

  4. 服务器调用量越来越大,服务器的容量问题如何评估?(评估用于扩容指标) 需要监控平台,监控调用量,响应事件

dubbo的核心功能

  1. 远程通信

  2. 集群容错

  3. 服务自动发现

  4. 负载均衡

  5. 基于url的总线驱动(所有信息都是通过url传递的)

dubbo的架构

核心角色:

  • Provider 提供服务,比如tomcat

  • Registry 注册中心,Provider将启动后的url注册到Registry

  • Consumer订阅Registry,Registry在发生变化时,将通知Consumer地址发生变化。

  • Consumer通过Registry提供的url 远程访问Provider

  • Monitor负责监控Consumer和Provider,解决调用关系以及调用量的监控问题

dubbo的简单使用

dubbo相关的demo位于: Github

构建provider

  1. 创建order-api模块,用于向其他模块提供接口。其中,此模块中只包含Java业务Server接口和输入输出对象。

  2. 创建order-provider模块,此模块依赖order-api模块,是order服务的具体实现;需要依赖dubbo与zkclient

  3. resources/META-INF/spring/目录下创建 order-consumer.xml 文件,用于定义dubbo服务

  4. 编写启动类,注册服务到注册中心zookeeper

  5. 查看zookeeper,发现dubbo节点下已经注册了一个url地址,使用此地址,可以直接调用dubbo服务: ![](../../../../../../OneDrive/note/Java/Distributed/images/20190313205831318_24519.png =687x)

创建consumer:

  1. 创建项目client,并在resources目录下创建配置文件order-consumer.xml,此配置文件用于配置远程代理对象:

  2. 使用Main启动consumer,并且利用创建好的服务代理对象调用服务:

dubbo-admin

dubbo-admin用来做服务治理,比如控制服务权重、服务路由等。

dubbo-admindubbo2.7时,被单独列入了一个仓库:Dubbo Admin Github;如果是2.6版本,则是在dubbo-admin模块中(地址)

将项目clone下来,可以依照README进行配置。

新的dubbo-admin项目结构如下:

其中,dubbo-admin-ui 是 前端项目,dubbo-admin-server 是接口服务。

  1. 修改 dubbo-admin-server\src\main\resources\application.properties文件的相关内容,配置注册中心地址,用户名密码等信息

  2. dubbo-admin-server 执行mvn clean package -Dmaven.test.skip=true 将项目打包为jar

  3. 执行jar文件,启动接口服务

  4. 进入dubbo-admin-ui 前端项目,执行 npm install

  5. 执行完毕后,使用npm run dev 或者 npm run build 运行项目,并打开网址测试

新的dubbo控制台界面如下:

image-20220307201955194

dubbo-monitor

dubbo-monitor用来监控服务的调用次数,调用关系、响应时间等。

dubbo-monitor-simple 是一个简单的dubbo监控平台,具体安装方式如下:

文件: dubbo-monitor-simple-2.5.3.zip

  1. 修改每个dubbo应用程序的xml文件,加入如下配置: <dubbo:monitor protocol="registry"/>,添加monitor监控

  2. 修改配置文件,如下:

  3. 执行bin/start.sh或者start.bat

  4. 访问localhost:8099:

启动服务检查

启动Consumer时,默认回去检测所依赖的服务是否正常提供服务。

即默认选项为 check=true;如果将check设置为false,则即使服务不可用,Consumer也可以正常启动。

除此之外,一下标签也拥有check属性:

  • dubbo:consumer, check=true/false: true,没有服务提供者的时候,报错

  • dubbo:registry, check=true/false: true,注册订阅失败时报错

telnet命令

Qos

参考Dubbo启动时qos-server can not bind localhost:22222错误解决

telnet 默认不可以远程调用,如需配置远程调用,需要加入如下参数:

其中,qos是指Quality of Service,是dubbo的在线运维命令,qos.enable代表是否开启在线运维命令,qos.accept.foreign.ip 是否可以远程连接,qos.portqos的端口(默认端口22222,如果被占用,则会抛出qos-server can not bind localhost:22222的错误)

多协议的支持

dubbo本身使用的RPC协议是dubbo协议(服务之间的通信协议),同时,dubbo也支持其他协议,比如:

  • dubbo

  • RMI

  • Hessian

  • WebService

  • Http

  • Thrift

Hessian 协议

Dubbo支持使用Hessian作为RPC协议,Hessian协议是Caucho开源的一个RPC框架,Hessian协议底层采用Http作为传输协议,序列化采用Hessian二进制序列化。

Hessian协议底层采用Http通讯,并使用JavaServlet暴露服务,缺省内嵌Jetty作为服务器实现。所以使用Hessian,需要添加两个包,Hessian和Jetty:

在Provider中添加对Hessian协议的支持:

此时查看注册中心,就会发现,在providers节点下,多出一个子节点:

客户端需要在调用服务时,指定所使用的RPC协议:

多注册中心支持(不常用)

针对部分服务发布到指定的注册中心,通常用于注册中心分组注册中心热备份等功能,实现很简单,只要在需要进行多注册中心的provider与consumer中添加多个不同的registry即可:

为指定的服务指定注册中心,只需要在<dubbo:service 上指定注册中心即可:

服务多版本支持

现在,针对OrderService,系统需要发布一个新的2.0版本,新增一个OrderService实现:OrderServiceImpl2

为了保证旧版用户正常使用,需要配置dubbo服务版本:

更新provider,在注册中心就会提供两个OrderService服务,一个版本1.0一个版本2.0:

![](../../../../../../OneDrive/note/Java/Distributed/images/20190318101350399_21345.png =730x)

comsumer在使用时,同样需要指定version:

异步调用

注意:异步调用只支持dubbo协议

调用接口时,调用过程可能较慢或者无需同步等待调用的返回结果,此时就需要异步调用。异步调用,服务端无需变动,只需要在客户端方面添加如下配置即可:

并使用RpcContext对象获取调用的返回结果:

主机绑定

provider发布服务时,ip地址是从何而来的?

绑定主机地址:

绑定后的ip:

![](../../../../../../OneDrive/note/Java/Distributed/images/20190318110512123_17445.png =834x)

服务只订阅

服务只订阅是指,在测试环境下,有可能需要调用注册中心的服务,但是又不能将当前服务注册到注册中心的情况,处理也很简单:

服务只注册

连接超时 timeout

一般情况下,一个服务允许的超时时间为 5~10 s。

服务集群和负载均衡

dubbo集群配置比较简单,不需要进行任何配置,只需将服务在其他机器上运行再向注册中心注册一次即可,代码就不再延时。

负载均衡策略

Dubbo共有以下几种负载均衡策略:

  • Random, 随机分配到某个服务,这是Dubbo默认的负载均衡策略

  • RoundRobin,轮询:按照公约后的权重设置轮询比率

  • LeastActive LoadBalance,最少活跃用数,即响应时间较短的服务优先

  • Consistent LoadBalance,一致性hash

四种负载均衡策略,位于源代码模块dubbo-clusterorg.apache.dubbo.rpc.cluster.loadbalance包下。

配置负载均衡策略

集群容错

dubbo提供了以下几种集群容错策略

  • failover cluster:失败时自动切换其他服务器。通过 retries=2 来设置重试次数;这是dubbo的默认策略

  • failfast cluster:快速失败,只发起一次调用。比如写操作,如新增数据,避免重复插入,这是非幂等请求(发起一次请求与发起多次请求所得的结果时不变的)

  • failsafe cluster:失败安全,即使失败也不抛异常,比如操作日志

  • failback cluster:失败自动恢复,后台记录失败请求,定时重发

  • forking cluster:并行调用多个服务器,只要有一个成功就返回,只能用于读请求(会浪费服务器资源)

  • broadcast cluster:广播调用所有提供者,其中一台报错就会抛出异常

配置集群容错:

服务配置优先级

dubbo 企业应用配置

代码展示

分包

  1. 将order-api与order-provider放入单一项目,其他user也放入单一项目,而不是全部采用多模块的方式放在一起。可以方便项目进行团队管理

  2. 服务接口、请求服务模型、异常信息都放在api模块下,复合重用等价原则,共同重用原则

  3. api模块中放入spring的引用配置,也可以放在模块的包目录下。com.xxx.xxx/xx-references.xml

粒度

  1. 尽可能将接口设置为粗粒度,每个服务方法代表一个独立的功能,而不是某个功能的步骤。否则会涉及到分布式事务

  2. 服务接口建议以业务场景为单位划分。并对相近业务进行抽象,防止接口暴增

  3. 不建议使用过于抽象的通用接口,比如泛型,这样的接口没有明确的语义,会使后期维护困难

版本

  1. 每个接口都应该定义版本,为后续的兼容性提供前瞻性考虑 (version),注意maven快照版本与发布版本的管理

  2. 建议使用两位版本号,第三位版本号则用于表示兼容性升级,只有不兼容时才需要变更服务版本

  3. 当接口做到不兼容升级的时候,先升级一半或者一台提供者为新版本,再将消费者全部升级为新版本,最后将所有提供者升级为新版本

推荐配置

  • 再provider端尽可能consumer端中需要配置的属性,比如timeout、retires、loadBalance、线程池大小

  • 配置管理员信息,即在application中配置的owner属性,建议配置多个,出问题可以找到相关人员

配置缓存文件

当注册中心集群出现问题,将会造成整个服务瘫痪,可以使用缓存文件,记录注册中心中的状态;当注册中心出现问题,将会从缓存文件中获取服务地址进行使用,进一步保证了服务的可用性。

缓存文件将会缓存:

  • 注册中心列表

  • 服务提供者列表

配置异常处理

尽量不要使用返回码作为返回信息,推荐使用异常代替。

最后更新于

这有帮助吗?