Dubbo架构进阶
Dubbo架构主要包含四个角色:消费者、提供者、注册中心和监控系统,如下图所示。
具体的交互流程是:消费者(Consumer)通过注册中心获取提供者(Provider)节点后,通过Dubbo的客户端SDK与Provider建立连接,并发起调用。Provider通过Dubbo的服务端SDK接收Consumer的请求,处理后再把结果返回给Consumer。
对于采用Dubbo进行RPC调用的解决方案,消费者和提供者都需要引入Dubbo的SDK来完成远程调用。因为Dubbo本身是采用Java实现的,所以要求服务消费者和服务提供者也都必须采用Java实现。不过开源社区已经开始使用对核心扩展点进行TCK(Technology CompatibilityKit)提升框架的兼容性。它为用户增加一种扩展实现,只需通过TCK,即可确保与框架的其他部分兼容运行,可以有效提高健壮性,也方便第三方接入。下面是Dubbo的官方详细架构。
● 左边部分是服务消费者使用的接口,右边部分是服务提供者使用的接口,位于中轴线上的为双方都用到的接口。
● 从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖关系,每一层都可以剥离上层被复用,其中Service 和 Config 层 为 API , 其 他 各 层 均 为 SPI ( ServiceProvider Interface)。
● 浅色小块为扩展接口,深色小块为实现类,图中只显示用于关联各层的实现类。
● 深色虚线为初始化过程,即启动时组装链,红色实线为方法调用过程,即运行时调时链,紫色三角箭头为继承(读者可到官网查看彩色图片),可以把子类看作父类的同一个节点,线上的文字为调用的方法。Dubbo服务调用过程Dubbo服务调用过程比较复杂,包含众多步骤,比如发送请求、编解码、服务降级、过滤器链处理、序列化、线程派发及响应请求等。
下面我们重点分析请求的发送与接收、编解码、线程派发及响应的发送与接收等过程。
Dubbo的服务调用过程
如下图所示。
首先服务消费者通过代理对象Proxy发起远程调用,接着通过网络客户端Client将编码后的请求发送给服务提供者的网络层,也就是Server。Server在收到请求后,首先要做的事情是对数据包进行解码。然后将解码后的请求发送至分发器Dispatcher,再由分发器将请求派发到指定的线程池上,最后由线程池调用具体的服务。这就是一个远程调用请求的发送与接收过程。
服务消费者发送请求
Dubbo支持同步和异步两种调用方式,其中异步调用还可细分为“有返回值”的异步调用和“无返回值”的异步调用。所谓“无返回值”的异步调用是指服务消费者只管调用,但不关心调用结果,此时Dubbo会直接返回一个空的RpcResult。若要使用异步特性,需要服务消费者手动进行配置。默认情况下,Dubbo使用同步调用方式。服务调用的线程栈快照如下图所示。
服务提供者接收请求
默认情况下,Dubbo使用Netty作为底层的通信框架。Netty首先会通过解码器对数据进行解码,并将解码后的数据传递给下一个处理器的指定方法。
解 码 器 将 数 据 包 解 析 成 Request 对 象 后 , NettyHandler