Dubbo的核心概念

 

先来回忆一下, 一个rpc远程服务调用, 咱们一般是怎么写的:

以http协议为例, 我们会封装一个http协议的客户端, 服务端可能是直接用spring mvc编写的restful服务

然后客户端把服务的地址通过spring注入或者直接从配置文件里读取.

整个调用过程如下图

clip_image001

Dubbo作为远程服务调用框架, 为了能在各环节都能灵活扩展, 在不同协议上能将调用过程标准化,

需要考虑的问题可远没那么简单, 他将RPC过程进行了细化分解, 高度抽象

下面是我在学习了dubbo源码之后, 对几个核心概念的理解:

  • 基本的, 定义客户端 服务端接口 Client, Server
  • 为了兼容不同的协议, 对不同协议的网络传输调用, 抽象出Transporter接口, 绑定服务url与处理回调方法. 对上层屏蔽底层不同协议处理方法.
  • 由于不同协议的交互数据, 行为不一致, 在传输层上, 又抽象了一层信息交互层(exchanger), 对上层提供了一致的消息传递处理方法, 一致的入参(Request), 回参(Response),消息回调方法(ExchangeHandler).
  • 为了进一步简化远程服务调用, 屏蔽调用处理细节, 使能够像调用本地方法一样调用远程服务. 也出于服务注册发现管理的需要, 又抽象出了一层Protocol层, 官方称之为远程调用层, 将调用方法,调用参数,参数类型封装到Invocation, 将结果封装到Result对象中, 返回给上层调用.对Protocol的调用上层来说, protocol接口核心主要做了两件事:暴露服务以及获得远程服务的引用
  • Invoker是Dubbo对方法的抽象, 在服务端, exporter通过protocol, 将invoker暴露出来.在客户端, 通过protocol获得一个远程服务引用, 封装为invoker给上层调用.
  • 再往上, 在业务层的业务bean, 如果要像调用本地方法一样调用服务, 不可能直接调用invoker吧, 于是中间还有一层代理层, 代理层将invoker转换成实现了业务服务接口的代理实例.
  • 为了能在服务调用过程中, 补充其他功能, 诸如记录日志, 权限控制,添加缓存,参数校验等, 使用过滤器模式对invoker进行处理返回.

下面是根据dubbo服务调用过程, 大致整理出来的一个比较粗略的调用关系图:

clip_image002

 

下面是Dubbo官方文档给出的说明, 将系统按功能分解为几个层次:

  • config,配置层,对外配置接口,以ServiceConfig, ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类
  • proxy,服务代理层,服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory
  • registry,注册中心层,封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory, Registry, RegistryService
  • cluster,路由层,封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster, Directory, Router, LoadBalance
  • monitor,监控层,RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory, Monitor, MonitorService
  • protocol,远程调用层,封将RPC调用,以Invocation, Result为中心,扩展接口为Protocol, Invoker, Exporter
  • exchange,信息交换层,封装请求响应模式,同步转异步,以Request, Response为中心,扩展接口为Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
  • transport,网络传输层,抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel, Transporter, Client, Server, Codec
  • serialize,数据序列化层,可复用的一些工具,扩展接口为Serialization, ObjectInput, ObjectOutput, ThreadPool

配置, 注册中心, 路由,监控,序列化暂不关注.

来看看, 其他每一层大致的类结构设计思路:

服务代理层:

image

ServiceConfig, ReferenceConfig 等需要获取invoker实例, 或者需要将invoker转成对应的代理的时候, 都能看到ProxyFactory的影子.

如在ServiceConfig中, 通过代理获得invoker, 并暴露服务.

Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);

 Exporter<?> exporter = protocol.export(invoker);

在ReferenceConfig中, 通过代理获得invoker对应的服务实例

private T createProxy(Map<String, String> map) {
 ……

// 创建服务代理
 return (T) proxyFactory.getProxy(invoker);
}
 

远程调用层(Protocol):

下面是Protocol层的几个核心接口, 可以看到Protocol接口主要负责将invoker包装为exporter对外发布,

同时也支持将远程服务url封装为invoker引用.

image

在protocol基类中, 会缓存暴露的及引用的invoker, 以便能统一对服务做管理, 比如destroy.

 

信息交换层(exchange):

下面是信息交换层的接口调用关系,

在服务端, 通过bind方法, 将一个服务url 绑定到一个消息处理方法.

在客户端, 通过connect方法, 同样把服务端返回的消息, 放到exchangeHandler中进行处理.

 

image

ExchangeHandler只有一个接口方法: reply, 从channel接收到request请求处理之后返回结果.

入参request是Request类型参数, 返回参数Object是Response类型, 在DecodeHandler中, 进行Request, Response类型的封装,解析.

public class HeaderExchanger implements Exchanger { 

 public static final String NAME = "header"; 

 public ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException { 

 return new HeaderExchangeClient(Transporters.connect(url, new DecodeHandler(new HeaderExchangeHandler(handler)))); 

 } 

 public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException { 

 return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))); 

 } 

 }

从DubboProtocol中ExchangeHandler可以看出, exchangeChannel可以得到invoker信息, 并从protocol中缓存的exporterMap里找到invoker引用.

网络传输层(transport):

110247_qYxb_661116.png

Transporter有MinaTransporter, NettyTransporter等实现, 对不同协议的Server, Client做了封装:

public class MinaTransporter implements Transporter {
    
    public static final String NAME = "mina";

    public Server bind(URL url, ChannelHandler handler) throws RemotingException {
        return new MinaServer(url, handler);
    }

    public Client connect(URL url, ChannelHandler handler) throws RemotingException {
        return new MinaClient(url, handler);
    }

}

以Netty为例, SimpleChannelHanlder是Netty自带的默认channel处理器, Dubbo设计了一个NettyHandler实现了dubbo的channelHandler与Netty channelHandler的对接.

转载于:https://my.oschina.net/u/661116/blog/697926

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值