概述
protocol 结构图
方法说明:
export 将方法暴露出去。
refer 引用 一个远程service。
destroy 销毁全部的 invoker(service 和refer)。
AbstractProtocol 分析
属性分析:
Map<String, Exporter<?>> exporterMap :
key是 监听 address (ip:port)。
Exporter<?> 主保留了暴露service 应用,提供unexport 。
方法分析:
destroy : 遍历 exporterMap 和 invokers 分别 unexport 和destory。
DubboProtocol 的分析
DubboProtocol 是默认的protocol实现。我们重点看下它的创建 和使用。
service 端作用
主要作用在:
com.alibaba.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol 方法。
调用 protocol.export方法暴露服务。
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
URL url = invoker.getUrl();
// export service.
String key = serviceKey(url);
// exporter 只是添加了Invoker key 的引用,方便 unexport
DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
exporterMap.put(key, exporter);
//export an stub service for dispatching event
Boolean isStubSupportEvent = url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT);
Boolean isCallbackservice = url.getParameter(Constants.IS_CALLBACK_SERVICE, false);
if (isStubSupportEvent && !isCallbackservice) {
String stubServiceMethods = url.getParameter(Constants.STUB_EVENT_METHODS_KEY);
if (stubServiceMethods == null || stubServiceMethods.length() == 0) {
if (logger.isWarnEnabled()) {
logger.warn(new IllegalStateException("consumer [" + url.getParameter(Constants.INTERFACE_KEY) +
"], has set stubproxy support event ,but no stub methods founded."));
}
} else {
stubServiceMethodsMap.put(url.getServiceKey(), stubServiceMethods);
}
}
// 创建 服务端 端口监听
openServer(url);
// Optimizing the serialization process for Kryo, FST
optimizeSerialization(url);
return exporter;
}
openServer:
根据当前URL (拿到address (ip:port))判断是否 已经创建server。没有则创建(调用createServer)加入到serverMap 。
createServer源码:
private ExchangeServer createServer(URL url) {
// send readonly event when server closes, it's enabled by default
url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
// enable heartbeat by default
url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);
if (str != null && str.length() > 0 && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))
throw new RpcException("Unsupported server type: " + str + ", url: " + url);
url = url.addParameter(Constants.CODEC_KEY, DubboCodec.NAME);
ExchangeServer server;
try {
// 这里开始 启动监听端口,requestHandler包含了具体处理请求的通信协议
server = Exchangers.bind(url, requestHandler);
} catch (RemotingException e) {
throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
}
str = url.getParameter(Constants.CLIENT_KEY);
if (str != null && str.length() > 0) {
Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
if (!supportedTypes.contains(str)) {
throw new RpcException("Unsupported client type: " + str);
}
}
return server;
}
说明:
- Exchangers 是一个工具类 包含 bind 和connect方法。
ExchangeClient 和 ExchangeServer 其实也都实现了 Client 和Server。为什么不直接使用低层的 nettyServer 和nettyClient,我觉得这里 ExchangeXXX在这里是一个装饰模式。
還有一個需要關注的是 java 对象 在远程传输 序列化实现。
dubboprotocol 采用的是 DubboCodec 继续跟踪 发现
Serialization s = CodecSupport.getSerialization(channel.getUrl(), proto);
里面默认采用的 hessian2
ps:
dubbo url 样例:
dubbo://10.62.0.117:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&bind.ip=10.62.0.117&bind.port=20880&channel.readonly.sent=true&codec=dubbo&dubbo=2.0.0&generic=false&heartbeat=60000&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=14232&qos.port=22222&side=provider×tamp=1523155912417
最后
以上就是精明饼干为你收集整理的dubbo分析-protocol 源码分析protocol 结构图DubboProtocol 的分析的全部内容,希望文章能够帮你解决dubbo分析-protocol 源码分析protocol 结构图DubboProtocol 的分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复