远程过程调用(RPC)框架

调用链路

Dubbo☆☆ - 图3

服务暴露过程

  • 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,注册到注册表中去
  • 成功

    服务调用过程

    image.png

    SPI

  • Java SPI:Java没IoC、AOP

  • 具体的SPI kv形式:静态代理

    容错机制

  • failover:直接切换

  • failfast:快速失败
  • failsafe
  • failback
  • forking cluster
  • broadcast cluster
  • 整合hystrix:失败回调、返回默认

    集群容错

    image.png

    降级

  • return null

  • 失败返回空

    负载均衡

  • 随机加权

  • 轮询
  • 最少活跃数
  • hash一致

    选举算法

注册中心

协议

  • dubbo:默认NIO单一长连接、二进制序列化 小数据量 100k、数据量中等 不适合文件传输
  • memcached
  • redis
  • WebService
  • http

概念

SOA服务治理框架
单一应用:ORM、垂直应用:MVC、分布式服务架构:RPC、流式计算架构:SOA

功能图
image.png

架构图
image.png

image.png

重要标签

@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
  • routers

    功能

  • 点对点直连

  • 只订阅
  • 多协议(大数据用短连接协议rmi,小数据大并发用长连接协议dubbo)
  • 多注册中心
  • 服务分组,分组聚合
  • 静态服务
  • 多版本(实现灰度发布)
  • 参数验证
  • 结果缓存
  • 泛化调用(用于测试)
  • 上下文信息
  • 回声测试
  • 异步执行(服务提供方,Dubbo内部线程池切换到业务线程池,无益于节省资源和提高RPC响应性能,提高吞吐量)
    image.png
  • 本地调用(节省时间)
  • 参数回调(TCP长连接双工通信,服务端调用客户端)Spring Cloud基于http是半双工的所以只能发起新的请求
  • 本地存根(客户端也执行一些代码,静态代理类似命令模式,ThreadLocal本地缓存/数据校验/降级等)
  • 本地伪装(mock,是stub的子类,只关注服务降级)
  • 并发控制(excutes actives,线程池隔离)
  • 连接控制(accepts connections长连接数量)
  • 配置规则
  • 优雅停机(kill PID / DubboShutdownHook.destroyAll())
  • 主机绑定
  • 令牌验证(token=”true”)

    特点

  • NIO Netty

    服务暴露过程

    https://www.jianshu.com/p/0939741e21e1
    服务暴露的整个过程大致可以分为四个阶段:

  • 创建invoker对象并对其加工

  • 开启netty服务,用于后续接收消费方发起的网络请求
  • 获取zookeeper连接并将服务注册成为zookeeper上的节点(服务引用的时候通过获取节点则能够找到provider然后建立网络连接)
  • 返回Exporter对象并放入ServiceConfig中的exporters变量中存储

image.png

服务引用过程

https://zhuanlan.zhihu.com/p/224938929
image.png
image.png
image.png

服务调用过程

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

SPI机制

image.png
https://dubbo.apache.org/zh/docs/v2.7/dev/source/dubbo-spi/
SPI实际上是“接口+策略模式+配置文件”实现的动态加载机制

支持负载均衡策略?

  • Random Loadbalance 随机
  • RoundRobin 轮询(卡在慢主机上)
  • LeastActive 最少活跃(越少调用越少发)
  • ConstantHash 一致性Hash(虚拟节点避免数据倾斜)

    支持多种容错策略

    image.png
    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
    image.png