Dubbo分布式服务框架整理
Dubbo 为分布式系统框架 底层RPC原理
Dubbo分层
Service层: Provider(服务提供者) 和 Consumer(消费者) ,由自己开发的接口
config层: 配置文件
proxy层: 代理,通过代理 负责provider,consumer之间互相通信,(无论consumer还是provider都需要代理)
registry层: 注册, provider注册自己作为一个服务,consumer去注册中心找要调的服务
cluster层: 一个provider可以部署在多台机器上,多个provider组成一个集群_cluster
monitor层: 监控层,监控provider被调用等信息
protocol层: 负责具体provider和consumer的通信
exchange层: 信息交换
serilaze层: 序列化
服务之间通信原理
1. 服务提供者向注册中心注册自己
2. 服务消费者从注册中心发现服务
3. 服务消费者通过动态代理创建代理类 来执行操作
4. 通过cluster负载均衡选择合适的服务机器来通信
5. 通过protocol选择对应的通信协议 (http协议 dubbo协议)
6. 通过exchange 封装request
7. 将请求序列化
8. 通过网络IO框架通信(Mina/Netty)
9.服务提供者通过代理类获取请求
注册中心挂了还可以继续通信,consumer本地有缓存 可以知道去哪找provider
Dubbo支持的通信协议
dubbo协议: 特点 长连接 + NIO异步通信 + hession序列化协议
http协议:
hessian协议:
长连接:建立一个永久连接,能持续发送请求
短连接:没发一次请求建立一次连接 请求结束断开
Dubbo负载均衡策略
对于同一个provider在多个机器上的请求分发
1. 顺序分发,按顺序雨露均沾到每台机器上
2.random loadbalance 随即分发,根据不同的机器性能调整权重
3.根据哈希路由,取模到对应的机器 (网关有一个负载均衡策略就是ip路由)
4.自动感知,某个机器性能越差,越不活跃,接到的请求就越少
集群容错策略
1.failover cluster模式 :失败自动切换,自动重试其他机器 常用于读操作
2.failfast cluster模式 : 一旦调用失败就立即失败 常用于写操作
3.failsafe cluster模式 : 出现异常时忽略掉 常用于日志服务等不重要调用
4.forking cluster模式 : 只要一个成功就立即返回
5.fallback cluster模式 : 失败了自动记录 然后定时重发 常用于消息队列这种
动态代理
默认使用javassist动态字节码生成,创建代理类
(可以通过SPI扩展机制培植自己的动态代理策略)
Dubbo SPI
Dubbo的SPI机制:
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
在Dubbo自己的jar中,/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件中 的配置信息:
dubbo = com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
http = com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
hession = com.alibaba.dubbo.rpc.protocol.hession.HessionProtocol
自己扩展SPI时:自己写个工程,打成jar包
在src/main/resources目录下,搞个META_INF/services
自己写个Protocol文件,Protocol文件里写 my = com.fuck.Myfuck
把jar包引入到dubbo 的provider的工程中,配置<dubbo:Protocol name="my" port="20000"/>
Dubbo服务治理,降级,重试
服务治理:
1.生产各个服务之间调用链路图,多个服务之间复杂调用关系图
2.各服务接口之间访问延迟,访问压力
3. 服务间调用失败处理
重试机制:
失败重试,
超时重试
服务降级:
服务调用失败几次 或者特定失败 做降级(返回个null或者做其他逻辑处理返回个结果)
保证幂等性:
1.通过唯一标识做幂等性保证,例如订单id,重复的请求相同的订单id不做处理。数据库唯一键插入失败 整个事务回滚
2.在缓存中加一个状态标识,每次请求先查redis看看状态标识是否存在了
保证消息顺序性:
1.基于分布式锁zookeper锁 每一个请求调用前都会尝试去获取zookeper锁,如果该请求未按顺序来的 则获取失败,再来下一个请求来尝试获取锁