一 RPC协议的网络传输
一个RPC协议又通信模块、报文编码和序列化三个模块组成,其中通信模块实现了RPC的网络传输。网络传输的稳定性和性能直接影响RPC服务的稳定性和性能。
网络传输框架组成
- io模型
(1)BIO:同步阻塞
(2)NIO:同步非阻塞(Netty)
(3)AIO:异步非阻塞 - 连接方式
(1)长连接(Netty)
(2)短链接 - 线程分类(每个线程都有配有线程池)
(1)IO线程
(2)服务端业务线程
(3)客户端调度线程
(4)客户端结果exchange线程
(5)心跳保活线程
(6)重连线程 - 线程池模型
(1)fix:固定线程池,此线程池启动时即创建固定大小的线程数,不做任何伸缩
(2)cached:缓存线程池,此线程池可伸缩,线程空闲一分钟后回收,新请求重新创建线程
(3)Limited:有限线程池,此线程池一直增长,直到上限,增长后不收缩。
二 dubbo传输模块的实现
(PS:本文只探讨dubbo协议的默认传输服务netty)
在创建连接之前,在客户端必须先创建出Client、服务端必须先创建出Server用于连接,而创建Client和Server是由DubboProtocol.java
调度的
服务端:
export()
方法进行服务暴露,又调用了openServer()
找到对应的Server,如果Server还没创建会调用createServer()
创建Server
调用链会传递url参数(该参数就是在配置文件配置的ip端口服务名称等),通过url产生唯一的Server,代表一个服务。
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
URL url = invoker.getUrl();
String key = serviceKey(url);
DubboExporter<T> exporter = new DubboExporter(invoker, key, this.exporterMap);
this.exporterMap.put(key, exporter);
Boolean isStubSupportEvent = url.getParameter("dubbo.stub.event", false);
Boolean isCallbackservice = url.getParameter("is_callback_service", false);
if (isStubSupportEvent && !isCallbackservice) {
String stubServiceMethods = url.getParameter("dubbo.stub.event.methods");
if (stubServiceMethods != null && stubServiceMethods.length() != 0) {
this.stubServiceMethodsMap.put(url.getServiceKey(), stubServiceMethods);
} else if (this.logger.isWarnEnabled()) {
this.logger.warn(new IllegalStateException("consumer [" + url.getParameter("interface") + "], has set stubproxy support event ,but no stub methods founded."));
}
}
this.openServer(url);
return exporter;
}
private void openServer(URL url) {
String key = url.getAddress();
boolean isServer = url.getParameter("isserver", true);
if (isServer) {
ExchangeServer server = (ExchangeServer)this.serverMap.get(key);
if (server == null) {
this.serverMap.put(key, this.createServer(url));
} else {
server.reset(url);
}
}
}
private ExchangeServer createServer(URL url) {
url = url.addParameterIfAbsent("channel.readonly.sent", Boolean.TRUE.toString());
url = url.addParameterIfAbsent("heartbeat", String.valueOf(60000));
String str = url.getParameter("server", "netty");
if (str != null &&