dubbo调用流程

[半转载]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/dubbo/dubbo-call-flow.html

img_1.png
img.png
补图备忘

概要精简版流程

  1. 客户端从注册中心拉取和订阅服务列表
  2. 聚合服务列表,形成Invoker
  3. 客户端通过路由和负载均衡选择合适的服务提供者
  4. 将请求交给底层的I/O线程池处理
  5. 在I/O线程池中进行序列化和反序列化等操作
  6. 将请求交给业务线程池处理业务方法调用
    Dubbo的调用流程主要在客户端完成,通过注册中心、路由、负载均衡等机制实现服务的发现和选择,然后通过底层的I/O线程池和业务线程池处理请求。这样的设计使得Dubbo具备高性能、高并发的特点,适用于分布式系统中的服务调用场景。

补充版流程

  1. 客户端启动时,会从注册中心拉取并订阅对应的服务列表。这些服务列表会被聚合成一个Invoker(调用器)。Cluster模块会将多个服务提供者聚合成一个Invoker。

  2. 在发起RPC调用之前,客户端会通过Directory#list方法获取服务提供者的地址列表,这些地址列表将被用于后续的路由和负载均衡操作。Dubbo内部还有一个实现了Directory接口的RegistryDirectory类,它和接口名是一对一的关系,负责拉取和订阅服务提供者、动态配置和路由项。

  3. 在Dubbo发起服务调用时,所有的路由和负载均衡操作都是在客户端进行的。首先会触发路由操作,然后将路由结果得到的服务列表作为负载均衡的参数。经过负载均衡算法的选择,将选出一台合适的机器进行RPC调用。

  4. 客户端经过路由和负载均衡后,将请求交给底层的I/O线程池(比如Netty)进行处理。I/O线程池主要负责处理读写、序列化和反序列化等操作。在这个阶段,必须避免阻塞操作,Dubbo提供了相应的参数控制。在处理反序列化对象时,可以选择在业务线程池中进行处理。

  5. 在整个流程中,涉及到两种线程池。一种是I/O线程池(比如Netty),主要负责底层的I/O操作。另一种是Dubbo业务线程池(Dubbo线程池):Dubbo还提供了一个业务线程池,用于承载业务方法的调用。在处理完底层的I/O操作后,Dubbo将请求交给业务线程池处理。这样可以避免阻塞I/O线程,提高系统的并发处理能力。

dubbo的多线程并发调用如何正确响应对应的线程(类似http2连接复用原理)

img2.png

  • 当客户端多个线程并发请求时,框架内部会调用DefaultFuture对象的get方法进行等待
  • 在请求发起时,框架内部会创建Request对象,这个时候会被分配一个唯一 id, DefaultFuture 可以从Request对象中获取id,并将关联关系存储到静态HashMap中,就是上图中的Futures 集合
  • 当客户端收到响应时,会根据Response对象中的id,从Futures集合中查找对应 DefaultFuture对象,最终会唤醒对应的线程并通知结果
  • 同时客户端也会启动一个定时扫描线程去 探测超时没有返回的请求

作者

神奇宝贝大师

发布于

2021-02-12

更新于

2023-04-11

许可协议

评论