Dubbo
Dubbo是阿里的分布式服务框架,基于zookeeper实现,已于12年底停止维护升级
Dubbox是当当团队基于dubbo升级的一个版本
与zookeeper的关系:Dubbo将注册中心进行抽象,使得它可以外接不同的存储媒介给注册中心提供服务,有ZooKeeper,Memcached,Redis等。
Dubbo各种各样的RPC、支持自定义协议、统一管理、统一监控、资源整合
dubbo,服务治理工具。实现系统之间通信。
1)服务提供者:启动时在指定端口上暴露服务,并将服务地址和端口注册到注册中心上。
2)服务消费者:启动时向注册中心订阅自己感兴趣的服务,以便获得服务提供方的地址列表。
3)注册中心,使用zookeeper实现,相当于房产中介。服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小,负责服务的注册和发现,负责保存服务提供方上报的地址信息,并向服务消费方推送。
4)监控中心:负责收集服务提供方和消费方的运行状态,比如服务调用次数、延迟等,用于监控。将dubbo的war工程部署到tomcat,进行一些配置,即可查看dubbo
5)运行容器:负责服务提供方的初始化、加载以及运行的生命周期管理。
部署阶段
服务提供者在指定端口暴露服务,并向注册中心注册服务信息。
服务消费者向注册中心发起服务地址列表的订阅。
运行阶段
注册中心向服务消费者推送地址列表信息。
服务消费者收到地址列表后,从其中选取一个向目标服务发起调用。
调用过程服务消费者和服务提供者的运行状态上报给监控中心。
Dubbo超时的实现原理
dubbo默认采用了netty作为网络组件,它属于一种NIO的模式。消费端发起远程请求后,线程不会阻塞等待服务端的返回,而是马上得到一个ResponseFuture,消费端通过不断的轮询机制判断是否有返回结果。因为是通过轮询,轮询有个需要特别注要的就是避免死循环,所以为了解决这个问题就引入了超时机制,只在一定时间范围内做轮询,如果超时就返回超时异常。
Dubbo超时重试机制带来的数据重复问题
常见的应用场景故障: 1、发送邮件(重复) ;2、账户注册(重复).。
解决方案:
1.对于核心的服务中心,去除dubbo超时重试机制,并重新评估设置超时时间。
(1)、去掉超时重试机制
<dubbo:provider delay="-1" timeout="6000" retries="0"/>
(2)、重新评估设置超时时间
<dubbo:service interface="*.*" ref="*" timeout="延长服务时间"/>
2.业务处理代码必须放在服务端,客户端只做参数验证和服务调用,不涉及业务流程处理
Dubbo的优势
- 服务注册中心
- 集群多种容错方案(ZK会通过心跳确认dubbo是否宕机)
-
- Failover Cluster(默认)
失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。
<dubbo:service retries="2" />
<dubbo:reference retries="2" />
<dubbo:reference> <dubbo:method name="findFoo" retries="2" /> </dubbo:reference>
-
- Failfast Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
-
- Failsafe Cluster
安全失败,出现异常时,直接忽略。通常用于写入审计日志等操作。
-
- Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
-
- Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数
-
- Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错 。通常用于通知所有提供者更新缓存或日志等本地资源信息
3. 直连提供者
在开发阶段为了方便测试,通常系统客户端能指定调用某个服务提供者,那么可以在引用服务时加一个url参数去指定服务提供者
4. 负载均衡:当有多个提供者在提供服务时,能够使用多种方案选择提供者
Random 随机选提供者,并可以给提供者设置权重
RoundRobin 轮询选择提供者
LeastActive 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash 一致性hash,相同参数的请求发到同一台机器上
服务端服务级别
<dubbo:service interface="..." loadbalance="roundrobin" />
客户端服务级别
<dubbo:reference interface="..." loadbalance="roundrobin" />
服务端方法级别
<dubbo:service interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/></dubbo:service>
客户端方法级别
<dubbo:reference interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/></dubbo:reference>
5、服务版本、服务分组
通过服务版本可以控制服务的不兼容升级,当同一个服务有多种实现时,可以使用服务分组进行区分
6、多协议
dubbo提供了多种协议给用户选择,如dubbo、hessian、rmi。并可为每个服务指定不同的传输协议,粒度可以细化到方法,不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议
分布式服务框架、RPC框架
分布式服务框架有:Dubbo、RMI 、Hessian、Webservice、Thrift、grpc(google)、motan、Spring Cloud…
- rpcx: 基于Go的服务治理的rpc框架、客户端支持跨语言
- grpc: Google 出品的跨语言rpc框架,很弱的(实验性的)负载均衡, 测试使用的是grpc-go
- go std rpc: Go标准库的rpc, 不支持跨语言(jsonrpc支持json rpc 1.0)
- thrift: 跨语言的rpc框架,facebook贡献
- dubbo: 国内较早开源的服务治理的Java rpc框架,虽然在阿里巴巴内部竞争中落败于HSF,沉寂了几年,但是在国内得到了广泛的应用,目前dubbo项目又获得了支持,并且dubbo 3.0也开始开发
- motan: 微博内部使用的rpc框架,底层支持java,生态圈往service mesh发展以支持多语言
- hprose: 国内开发人员开发的一个跨语言的rpc框架,非服务治理但是性能高效
- twirp: twitch.tv刚刚开源的一个restful风格的rpc框架
- go-micro: Go语言的一个服务治理rpc框架, 在测试中发现性能不太好,所以没有继续测试,相关的测试代码已在github库中
- go kit:
- 腾讯 Tars:腾讯公司的rpc框架
- 百度 brpc: 百度公司的rpc框架
- spring cloud:
发展历史:
1、为了不同语言构造的系统之间能够互相调用
出现了webservice :不同系统之间交互数据的时候,采用同一种数据格式xml,这种协议称为soap,soap 协议可以基于http协议传输数据,也可以基于ftp smtp 等其他协议传递数据,但是大多数都是基于http 。
2、客户端不知道该传递什么参数,不知道远程服务器有提供哪些服务
出现了webservice的接口说明文档wsdl,用这种文档来说明接口的详情
3、除了webservice 的思想,还有一部分的思想是,不同的语言之间可以建立一种第三方语言,大家可以建立自己对第三方语言的映射
- PHPRPC,Hessian,JSON-RPC
- 框架:
- Microsoft WCF,WebAPI
- ZeroC Ice,Thrift,GRPC protocol buffer
- Hprose
两种思想的优缺点比较:
首先,都实现了跨语言,这是可以称赞的。
webservice 的缺点: soap 协议 消息封装太复杂,采用xml 传输数据,网络消耗和 cpu 解析消耗都特别大,不适合传递大量数据,客户端需要生成很多stub 类。
rpc 框架 : 传输数据多采用二进制格式 ,消息序列化和反序列化都比较快,网络消耗小,缺点是客户端和服务端都要生成很多stub类。
如果 idl 做了修改, 还要重新生成一遍 stub 类。
参考链接: