远程过程调用(RPC)框架
调用链路
服务暴露过程
- IoC启动加载Dubbo配置的标签
- 解析标签ServiceBean会生成一个Bean
- 实现了InitializingBean:afterpropertiesSet(get provider、set provider、各种信息保存在ServiceBean)
- IoC完成,还实现了一个ApplicationListener监听器:回调onapplicationEvent,是否暴露 不是延迟暴露
暴露:信息校验doexport(检查、doexportUrl暴露URL(加载注册中心、循环协议 端口(代理工厂获取invoke封装(暴露invoke(根据spi来、本地暴露、打开服务器exchangeServer、启动服务器netty监听端口、注册中心注册服务 注册表 执行器、暴露p和s两个invoke的map保存了地址)、spi)))
服务引用过程
factorybean->getObject->get:init
- 信息检查:创建代理对象createProxy
- 远程引用,获取到zk,获取到信息,订阅:dubbo执行远程引用
- 创建Netty客户端:返回invoke,注册到注册表中去
-
服务调用过程
SPI
Java SPI:Java没IoC、AOP
-
容错机制
failover:直接切换
- failfast:快速失败
- failsafe
- failback
- forking cluster
- broadcast cluster
-
集群容错
降级
return null
-
负载均衡
随机加权
- 轮询
- 最少活跃数
- hash一致
选举算法
注册中心
协议
- dubbo:默认NIO单一长连接、二进制序列化 小数据量 100k、数据量中等 不适合文件传输
- memcached
- redis
- WebService
- http
概念
SOA服务治理框架
单一应用:ORM、垂直应用:MVC、分布式服务架构:RPC、流式计算架构:SOA
功能图

架构图


重要标签
@EnableDubbo(@EnableDubboConfig创建bean配置类并且进行数据绑定)
@Service
@Reference(check=false)
UserService userService;
配置覆盖
Dubbo线程模型
服务隔离(限流)——线程池(相对于IO请求)
Dispatcher(all/direct/message/execution/connection)、ThreadPool(fixed/cached/limited/eager/)
四个节点
- configurators(override://覆盖运行时的某些属性)
- providers
- consumers
-
功能
点对点直连
- 只订阅
- 多协议(大数据用短连接协议rmi,小数据大并发用长连接协议dubbo)
- 多注册中心
- 服务分组,分组聚合
- 静态服务
- 多版本(实现灰度发布)
- 参数验证
- 结果缓存
- 泛化调用(用于测试)
- 上下文信息
- 回声测试
- 异步执行(服务提供方,Dubbo内部线程池切换到业务线程池,无益于节省资源和提高RPC响应性能,提高吞吐量)

- 本地调用(节省时间)
- 参数回调(TCP长连接双工通信,服务端调用客户端)Spring Cloud基于http是半双工的所以只能发起新的请求
- 本地存根(客户端也执行一些代码,静态代理类似命令模式,ThreadLocal本地缓存/数据校验/降级等)
- 本地伪装(mock,是stub的子类,只关注服务降级)
- 并发控制(excutes actives,线程池隔离)
- 连接控制(accepts connections长连接数量)
- 配置规则
- 优雅停机(kill PID / DubboShutdownHook.destroyAll())
- 主机绑定
-
特点
-
服务暴露过程
https://www.jianshu.com/p/0939741e21e1
服务暴露的整个过程大致可以分为四个阶段: 创建invoker对象并对其加工
- 开启netty服务,用于后续接收消费方发起的网络请求
- 获取zookeeper连接并将服务注册成为zookeeper上的节点(服务引用的时候通过获取节点则能够找到provider然后建立网络连接)
- 返回Exporter对象并放入ServiceConfig中的exporters变量中存储
服务引用过程
https://zhuanlan.zhihu.com/p/224938929

服务调用过程
https://dubbo.apache.org/zh/docs/v2.7/dev/source/service-invoking-process/
首先服务消费者通过代理对象 Proxy 发起远程调用,接着通过网络客户端 Client 将编码后的请求发送给服务提供方的网络层上,也就是 Server。Server 在收到请求后,首先要做的事情是对数据包进行解码。然后将解码后的请求发送至分发器 Dispatcher,再由分发器将请求派发到指定的线程池上,最后由线程池调用具体的服务。这就是一个远程调用请求的发送与接收过程。至于响应的发送与接收过程,这张图中没有表现出来。对于这两个过程,我们也会进行详细分析。
SPI机制

https://dubbo.apache.org/zh/docs/v2.7/dev/source/dubbo-spi/
SPI实际上是“接口+策略模式+配置文件”实现的动态加载机制
支持负载均衡策略?
- Random Loadbalance 随机
- RoundRobin 轮询(卡在慢主机上)
- LeastActive 最少活跃(越少调用越少发)
- ConstantHash 一致性Hash(虚拟节点避免数据倾斜)
支持多种容错策略

4+2
Failover Cluste:失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries=”2” 来设置重试次数(不含第一次)。默认容错机制
Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
Failback Cluster :失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=”2” 来设置最大并行数。
Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。Dubbo/gRPC/Thift/Motan区别
Dubbo,阿里用的人多,功能支持非常全,不能跨语言通讯
Motan,微博,只支持java,支持注册与发现,序列化Hessian2、JSON、扩展
Thift,需要写API的定义文件,支持跨语言通讯,支持多种网络模型和线程模型,序列化Thrift,不支持注册与发现
gRPC,需要写API的定义文件,支持跨语言通讯,序列化protobuf,基于HTTP2
