先来回忆一下, 一个rpc远程服务调用, 我们通常是怎么写的:java
以http协议为例, 咱们会封装一个http协议的客户端, 服务端多是直接用spring mvc编写的restful服务spring
而后客户端把服务的地址经过spring注入或者直接从配置文件里读取.缓存
整个调用过程以下图服务器
Dubbo做为远程服务调用框架, 为了能在各环节都能灵活扩展, 在不一样协议上能将调用过程标准化,restful
须要考虑的问题可远没那么简单, 他将RPC过程进行了细化分解, 高度抽象网络
下面是我在学习了dubbo源码以后, 对几个核心概念的理解:mvc
下面是根据dubbo服务调用过程, 大体整理出来的一个比较粗略的调用关系图:负载均衡
下面是Dubbo官方文档给出的说明, 将系统按功能分解为几个层次:框架
配置, 注册中心, 路由,监控,序列化暂不关注.异步
来看看, 其余每一层大体的类结构设计思路:
服务代理层:
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引用.
在protocol基类中, 会缓存暴露的及引用的invoker, 以便能统一对服务作管理, 好比destroy.
信息交换层(exchange):
下面是信息交换层的接口调用关系,
在服务端, 经过bind方法, 将一个服务url 绑定到一个消息处理方法.
在客户端, 经过connect方法, 一样把服务端返回的消息, 放到exchangeHandler中进行处理.
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):
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的对接.