本文将深入分析dubbo的服务发布涉及到的流程及主要类的代码。首先,我们先从类的关系图来看一下dubbo发布服务涉及到的相关类。

1.类图

上图展示了部分服务发布过程中需要使用到的类和接口,其中:

spring适配涉及到的类:DubboNamespaceHandler、DubboBeanDefinitionParser、ServiceBean;

配置信息存储:ServicdConfig、RegistryConfig、MonitorConfig、ProtocolConfig、ProviderConfig等;

应用协议:Protocol、DubboProtocol、HessianProtocol、ThriftProtocol、RmiProtocol、AbstractProxyProtocol、AbstractProtocol等;

Server相关:Exchanger、HeaderExchanger、ExchangeServer、HeaderExchangeServer、Transporters、Transporter、NettyTransporter、NettyServer等;

2.时序图

我们通过时序图来分析一下在发布服务的过程中,上面的类是如何串联在一起的:

a.spring容器通过DubboBeanDefinitionParser类的对象来解析xml文件中的标签,生成ServiceConfig等配置对象;

b.ServiceConfig的export()等发布服务的方法被调用;

c.通过spi机制确定Protocol接口的实现对象为DubboProtocol的对象,调用它的openServer()等方法;

d.通过spi机制确定Transporter接口的实现对象为NettyTransporter,调用它的bind()方法;

e.调用NettyServer类,启动netty服务,绑定端口。

3.核心代码解析

a.DubboProtocol

public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {URL url = invoker.getUrl();//获取url信息// export service.String key = serviceKey(url);//产生与发布的接口映射的key ,格式例如:com.alibaba.dubbo.demo.DemoService:20882DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);//创建DubboExporter对象exporterMap.put(key, exporter);//缓存此对象//export an stub service for dispaching eventBoolean 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);//打开服务return exporter;
}private void openServer(URL url) {// find server.String key = url.getAddress();//client 也可以暴露一个只有server可以调用的服务。boolean isServer = url.getParameter(Constants.IS_SERVER_KEY,true);if (isServer) {ExchangeServer server = serverMap.get(key);if (server == null) {serverMap.put(key, createServer(url));//创建新的服务} else {//server支持reset,配合override功能使用
            server.reset(url);}}
}private ExchangeServer createServer(URL url) {//默认开启server关闭时发送readonly事件url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());//默认开启heartbeaturl = 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, Version.isCompatibleVersion() ? COMPATIBLE_CODEC_NAME : DubboCodec.NAME);ExchangeServer server;try {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;

  b.NettyServer

protected void doOpen() throws Throwable {NettyHelper.setNettyLoggerFactory();ExecutorService boss = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerBoss", true));//boss线程池ExecutorService worker = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerWorker", true));//工作线程池ChannelFactory channelFactory = new NioServerSocketChannelFactory(boss, worker, getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS));bootstrap = new ServerBootstrap(channelFactory);//服务启动类final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);channels = nettyHandler.getChannels();// https://issues.jboss.org/browse/NETTY-365// https://issues.jboss.org/browse/NETTY-379// final Timer timer = new HashedWheelTimer(new NamedThreadFactory("NettyIdleTimer", true));bootstrap.setPipelineFactory(new ChannelPipelineFactory() {public ChannelPipeline getPipeline() {NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec() ,getUrl(), NettyServer.this);ChannelPipeline pipeline = Channels.pipeline();/*int idleTimeout = getIdleTimeout();if (idleTimeout > 10000) {pipeline.addLast("timer", new IdleStateHandler(timer, idleTimeout / 1000, 0, 0));}*/pipeline.addLast("decoder", adapter.getDecoder());//增加解码器pipeline.addLast("encoder", adapter.getEncoder());//增加编码器pipeline.addLast("handler", nettyHandler);//业务处理类return pipeline;}});// bindchannel = bootstrap.bind(getBindAddress());
}

dubbo源码分析二:服务发布相关推荐

  1. dubbo源码分析7 之 服务本地暴露

    在上一篇文章我们分析了一下 dubbo 在服务暴露发生了哪些事,今天我们就来分析一下整个服务暴露中的本地暴露.(PS:其实我感觉本地暴露蛮鸡肋的).本地暴露需要服务提供方与服务消费方在同一个 JVM. ...

  2. apache dubbo 源码分析系列汇总

    Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成.后面捐献给了知名的开源社区 ...

  3. Dubbo 源码分析 - 服务导出

    1.服务导出过程 本篇文章,我们来研究一下 Dubbo 导出服务的过程.Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可 ...

  4. 视频教程-RPC服务框架(Dubbo)源码分析-Java

    RPC服务框架(Dubbo)源码分析 鲁班学院-子路老师曾就职于谷歌.天猫电商等多家互联网公司,历任java架构师.研发经理等职位,参与并主导千万级并发电商网站与后端供应链研发体系搭建,多次参与电商大 ...

  5. Dubbo源码分析:全集整理

    文章目录 一.前言 二.目录 1. 源码篇 2. 衍生篇 一.前言 本文是Dubbo源码分析目录集整理,方便后续查找. 本文持续更新中.文章内容尚在修改中, 受限于个人能力和理解偏差,该系列文章部分内 ...

  6. Dubbo 源码分析 - 集群容错之 LoadBalance

    1.简介 LoadBalance 中文意思为负载均衡,它的职责是将网络请求,或者其他形式的负载"均摊"到不同的机器上.避免集群中部分服务器压力过大,而另一些服务器比较空闲的情况.通 ...

  7. Dubbo 源码分析 - 集群容错之 Router

    1. 简介 上一篇文章分析了集群容错的第一部分 – 服务目录 Directory.服务目录在刷新 Invoker 列表的过程中,会通过 Router 进行服务路由.上一篇文章关于服务路由相关逻辑没有细 ...

  8. dubbo源码分析系列(1)扩展机制的实现

    1 系列目录 dubbo源码分析系列(1)扩展机制的实现 dubbo源码分析系列(2)服务的发布 dubbo源码分析系列(3)服务的引用 dubbo源码分析系列(4)dubbo通信设计 2 SPI扩展 ...

  9. dubbo(5) Dubbo源码解析之服务调用过程

    来源:https://juejin.im/post/5ca4a1286fb9a05e731fc042 Dubbo源码解析之服务调用过程 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与 ...

最新文章

  1. 【MAVEN】如何在Eclipse中创建MAVEN项目
  2. linux小红帽系统能用微信,小红帽腾讯QQ微信登录版-小红帽腾讯版v1.0.3 安卓版-腾牛安卓网...
  3. ASP连接11种数据库的常用语法
  4. 现代软件工程第六章作业
  5. H - Color the ball(树状数组)(区间更新)(求单点)(线段树)
  6. mp3太大怎么压缩变小?
  7. windows10计算机用户密码,win10系统更改administrator账户密码图文教程
  8. 安装win10专业版步骤
  9. Synergy Mac和Win键盘映射
  10. Android开发周报:Android Studio2.0发布、Activity动态创建
  11. java doc转换docx_JAVA - 将doc文档转为docx文档
  12. android 音频播放时小喇叭动画
  13. 远光天擎 | 研发运维一体化智能云平台
  14. Python的人工智能模拟框架
  15. 【操作系统】进程-哲学家进餐问题
  16. MinGW下载和安装教程
  17. neovim as JavaScript IDE
  18. 大数据技术中的伦理问题
  19. java运行库一键修复_在运行时修补Java
  20. qimage 像素 替换颜色_米8精简版拥有24MP前置摄像头与使用超级像素技术索尼IMX576传感器...

热门文章

  1. leangoo如何邀请成员加入看板?
  2. CentOS YUM / RPM Error Signature Key ID BAD
  3. JAVA设计模式--辛格尔顿
  4. DNS 学习笔记之5- DNS区域详解
  5. android jni 字符串拼接,JNI 字符串拼接方法
  6. mysql启动集群报连接本地失败_启动本地安装的pxc集群失败,前面的步骤都检查没错了...
  7. CompletableFuture异步调用
  8. RocketMQ为什么速度快
  9. 通过ObjectProvider进行依赖查找
  10. Redis中的Lua脚本超时