操作流程图
1. 服务注册, 故障及下线
- 注册: provider和consumer同时在zk上注册临时节点, 同时consumer订阅zk /dubbo/**/providers provider地址, providers发生变化, zk自动推送给consumer
zk上结构如下
ls /dubbo/cn.xxx.xxxService
[consumers, routers, providers, configurators]
[consumer://机器ip/接口?application=服务名&category=consumers&check=false&default.check=false&default.group=beta&default.timeout=5000&default.version=1.0.0&dubbo=2.6.2&interface=接口&methods=方法1,方法2&pid=7828&revision=0.0.1&side=consumer×tamp=1556173624632]
[dubbo://机器1ip:端口/接口?anyhost=true&application=WalletOrderApplicationConsumer&delay=2000&dubbo=2.5.3&group=beta&heartbeat=10000&interface=接口&methods=方法1,方法2&pid=22419&retries=0&revision=1.0.0&side=provider&timeout=10000×tamp=1564743170669&version=1.0.0,
dubbo://机器2ip:端口/接口?anyhost=true&application=WalletOrderApplicationConsumer&delay=2000&dubbo=2.5.3&group=beta&heartbeat=10000&interface=cn.ipaynow.webank.wallet.order.api.provider.DataCenterTaskService&methods=syncRechargesRefund,syncTrans,syncTransCancel,syncTransRefunds,syncRecharges&pid=16801&retries=0&revision=0.0.1&side=provider&timeout=10000×tamp=1563792977340&version=1.0.0]
- 故障: zk自动删除临时节点
-
2. Proxy 动态代理
根据配置的接口, 生成动态代理对象, 使用 JDK + JAVAASSIST 方式
在服务提供端,将服务的具体实现类转为Invoker
- 在消费端,通过 getProxy(Invoker invoker)将invoker转为客户端需要的接口
Invoker封装了Provider地址及Service接口信息
3. Cluster 集群层
获取到要调用的Invoker
多个服务端会有多个 Invoker对象, 组合成Directory, Directory在zk推送Provider节点变更时, 会发生变化
- Router, 按照路由规则选出本次可以调用的 Directory子集, zk注册中心 routers节点下配置
- LoadBalance 从子集中按照负载均衡选出本次调用
- Random LoadBalance 随机
- RoundRobin LoadBalance 轮询
- LeastActive LoadBalance 最少活跃
- ConsistentHash LoadBalance 一致性哈希
- 容错
- Failover Cluster 失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries=”2″ 来设置重试次数(不含第一次)。
- Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
- Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
- Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
- Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=”2″ 来设置最大并行数。
4. Protocol 远程调用层
包含两个接口, 分别是 暴露服务(export) 和 引用服务(refer) 分别对应provider 和 consumer
选择通信协议 dubbo, hessian, http等5. Exchange 数据交换层
将请求信息封装为Request, 然后发送给 Transport层, 并将返回信息封装为Response6. Transport 网络传输层
使用netty或mina进行网络通信7. serialize 序列化层
将请求报文和返回报文记性序列化和反序列化8. provider收到请求后先进行反序列化, 然后在解析请求, 通过动态代理调用相应方法