太令人吃惊了,Dubbo 服务发布-原理解析就这么轻松自然的梳理完了!

简介: Dubbo 服务发布-原理解析

服务发布-原理

第一个发布的动作:暴露本地服务

   Export dubbo service com.alibaba.dubbo.demo.DemoService to local registry, dubbo version: 2.0.0, current host: 127.0.0.1

第二个发布动作:暴露远程服务

   Export dubbo service com.alibaba.dubbo.demo.DemoService to url dubbo://192.168.100.38:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=8484&side=provider&timestamp=1473908495465, dubbo version: 2.0.0, current host: 127.0.0.1

   Register dubbo service com.alibaba.dubbo.demo.DemoService url dubbo://192.168.100.38:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&monitor=dubbo%3A%2F%2F192.168.48.117%3A2181%2Fcom.alibaba.dubbo.registry.RegistryService%3Fapplication%3Ddemo-provider%26backup%3D192.168.48.120%3A2181%2C192.168.48.123%3A2181%26dubbo%3D2.0.0%26owner%3Dwilliam%26pid%3D8484%26protocol%3Dregistry%26refer%3Ddubbo%253D2.0.0%2526interface%253Dcom.alibaba.dubbo.monitor.MonitorService%2526pid%253D8484%2526timestamp%253D1473908495729%26registry%3Dzookeeper%26timestamp%3D1473908495398&owner=william&pid=8484&side=provider&timestamp=1473908495465 to registry registry://192.168.48.117:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&backup=192.168.48.120:2181,192.168.48.123:2181&dubbo=2.0.0&owner=william&pid=8484&registry=zookeeper&timestamp=1473908495398, dubbo version: 2.0.0, current host: 127.0.0.1

第三个发布动作:启动netty

   Start NettyServer bind /0.0.0.0:20880, export /192.168.100.38:20880, dubbo version: 2.0.0, current host: 127.0.0.1

第四个发布动作:打开连接zk

   INFO zookeeper.ClientCnxn: Opening socket connection to server /192.168.48.117:2181

第五个发布动作:到zk注册

   Register: dubbo://192.168.100.38:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=8484&side=provider&timestamp=1473908495465, dubbo version: 2.0.0, current host: 127.0.0.1

第六个发布动作;监听zk

   Subscribe: provider://192.168.100.38:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=8484&side=provider&timestamp=1473908495465, dubbo version: 2.0.0, current host: 127.0.0.1

   Notify urls for subscribe url provider://192.168.100.38:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=8484&side=provider&timestamp=1473908495465, urls: [empty://192.168.100.38:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=8484&side=provider&timestamp=1473908495465], dubbo version: 2.0.0, current host: 127.0.0.1

暴露本地服务和暴露远程服务的区别是什么?

1.暴露本地服务:指暴露在用一个JVM里面,不用通过调用zk来进行远程通信。例如:在同一个服务,自己调用自己的接口,就没必要进行网络IP连接来通信。

2.暴露远程服务:指暴露给远程客户端的IP和端口号,通过网络来实现通信。

zk持久化节点 和临时节点有什么区别?

持久化节点:一旦被创建,触发主动删除掉,否则就一直存储在ZK里面。

临时节点:与客户端会话绑定,一旦客户端会话失效,这个客户端端所创建的所有临时节点都会被删除。

ServiceBean.onApplicationEvent

-->export()

 -->ServiceConfig.export()

   -->doExport()

     -->doExportUrls()//里面有一个for循环,代表了一个服务可以有多个通信协议,例如 tcp协议 http协议,默认是tcp协议

       -->loadRegistries(true)//从dubbo.properties里面组装registry的url信息

       -->doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs)

         //配置不是remote的情况下做本地暴露 (配置为remote,则表示只暴露远程服务)

         -->exportLocal(URL url)

           -->proxyFactory.getInvoker(ref, (Class) interfaceClass, local)

             -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension("javassist");

             -->extension.getInvoker(arg0, arg1, arg2)

               -->StubProxyFactoryWrapper.getInvoker(T proxy, Class<T> type, URL url)

                 -->proxyFactory.getInvoker(proxy, type, url)

                   -->JavassistProxyFactory.getInvoker(T proxy, Class<T> type, URL url)

                     -->Wrapper.getWrapper(com.alibaba.dubbo.demo.provider.DemoServiceImpl)

                       -->makeWrapper(Class<?> c)

                     -->return new AbstractProxyInvoker<T>(proxy, type, url)

           -->protocol.export

             -->Protocol$Adpative.export

               -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension("injvm");

               -->extension.export(arg0)

                 -->ProtocolFilterWrapper.export

                   -->buildInvokerChain //创建8个filter

                   -->ProtocolListenerWrapper.export

                     -->InjvmProtocol.export

                       -->return new InjvmExporter<T>(invoker, invoker.getUrl().getServiceKey(), exporterMap)

                       -->目的:exporterMap.put(key, this)//key=com.alibaba.dubbo.demo.DemoService, this=InjvmExporter

         //如果配置不是local则暴露为远程服务.(配置为local,则表示只暴露本地服务)

         -->proxyFactory.getInvoker//原理和本地暴露一样都是为了获取一个Invoker对象

         -->protocol.export(invoker)

           -->Protocol$Adpative.export

             -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension("registry");

               -->extension.export(arg0)

                 -->ProtocolFilterWrapper.export

                   -->ProtocolListenerWrapper.export

                     -->RegistryProtocol.export

                       -->doLocalExport(originInvoker)

                         -->getCacheKey(originInvoker);//读取 dubbo://192.168.100.51:20880/

                         -->rotocol.export

                           -->Protocol$Adpative.export

                             -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension("dubbo");

                             -->extension.export(arg0)

                               -->ProtocolFilterWrapper.export

                                 -->buildInvokerChain//创建8个filter

                                 -->ProtocolListenerWrapper.export

---------1.netty服务暴露的开始-------    -->DubboProtocol.export

                                     -->serviceKey(url)//组装key=com.alibaba.dubbo.demo.DemoService:20880

                                     -->目的:exporterMap.put(key, this)//key=com.alibaba.dubbo.demo.DemoService:20880, this=DubboExporter

                                     -->openServer(url)

                                       -->createServer(url)

--------2.信息交换层 exchanger 开始-------------->Exchangers.bind(url, requestHandler)//exchaanger是一个信息交换层

                                           -->getExchanger(url)

                                             -->getExchanger(type)

                                               -->ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension("header")

                                           -->HeaderExchanger.bind

                                             -->Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))

                                               -->new HeaderExchangeHandler(handler)//this.handler = handler

                                               -->new DecodeHandler

                                                   -->new AbstractChannelHandlerDelegate//this.handler = handler;

---------3.网络传输层 transporter--------------------->Transporters.bind

                                                 -->getTransporter()

                                                   -->ExtensionLoader.getExtensionLoader(Transporter.class).getAdaptiveExtension()

                                                 -->Transporter$Adpative.bind

                                                   -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.remoting.Transporter.class).getExtension("netty");

                                                   -->extension.bind(arg0, arg1)

                                                     -->NettyTransporter.bind

                                                       --new NettyServer(url, listener)

                                                         -->AbstractPeer //this.url = url;    this.handler = handler;

                                                         -->AbstractEndpoint//codec  timeout=1000  connectTimeout=3000

                                                         -->AbstractServer //bindAddress accepts=0 idleTimeout=600000

---------4.打开断开,暴露netty服务-------------------------------->doOpen()

                                                           -->设置 NioServerSocketChannelFactory boss worker的线程池 线程个数为3

                                                           -->设置编解码 hander

                                                           -->bootstrap.bind(getBindAddress())

                                               -->new HeaderExchangeServer

                                                 -->this.server=NettyServer

                                                 -->heartbeat=60000

                                                 -->heartbeatTimeout=180000

                                                 -->startHeatbeatTimer()//这是一个心跳定时器,采用了线程池,如果断开就心跳重连。

                       -->getRegistry(originInvoker)//zk 连接

                         -->registryFactory.getRegistry(registryUrl)

                           -->ExtensionLoader.getExtensionLoader(RegistryFactory.class).getExtension("zookeeper");

                           -->extension.getRegistry(arg0)

                             -->AbstractRegistryFactory.getRegistry//创建一个注册中心,存储在REGISTRIES

                               -->createRegistry(url)

                                 -->new ZookeeperRegistry(url, zookeeperTransporter)

                                   -->AbstractRegistry

                                     -->loadProperties()//目的:把C:\Users\bobo\.dubbo\dubbo-registry-192.168.48.117.cache

                                                                                                                                                                       文件中的内容加载为properties

                                     -->notify(url.getBackupUrls())//不做任何事            

                                   -->FailbackRegistry  

                                     -->retryExecutor.scheduleWithFixedDelay(new Runnable()//建立线程池,检测并连接注册中心,如果失败了就重连

                                   -->ZookeeperRegistry

                                     -->zookeeperTransporter.connect(url)

                                       -->ZookeeperTransporter$Adpative.connect(url)

                                         -->ExtensionLoader.getExtensionLoader(ZookeeperTransporter.class).getExtension("zkclient");

                                         -->extension.connect(arg0)

                                           -->ZkclientZookeeperTransporter.connect

                                             -->new ZkclientZookeeperClient(url)

                                               -->AbstractZookeeperClient

                                               -->ZkclientZookeeperClient

                                                 -->new ZkClient(url.getBackupAddress());//连接ZK

                                                 -->client.subscribeStateChanges(new IZkStateListener()//订阅的目标:连接断开,重连

                                       -->zkClient.addStateListener(new StateListener()

                                         -->recover //连接失败 重连

                                         

                       -->registry.register(registedProviderUrl)//创建节点

                         -->AbstractRegistry.register

                         -->FailbackRegistry.register

                           -->doRegister(url)//向zk服务器端发送注册请求

                             -->ZookeeperRegistry.doRegister

                               -->zkClient.create

                                 -->AbstractZookeeperClient.create//dubbo/com.alibaba.dubbo.demo.DemoService/providers/

                                                                     dubbo%3A%2F%2F192.168.100.52%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26

                                                                     application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3D

                                                                     com.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3

                                                                     Dwilliam%26pid%3D2416%26side%3Dprovider%26timestamp%3D1474276306353

                                   -->createEphemeral(path);//临时节点  dubbo%3A%2F%2F192.168.100.52%3A20880%2F.............

                                   -->createPersistent(path);//持久化节点 dubbo/com.alibaba.dubbo.demo.DemoService/providers

                                       

                                       

                       -->registry.subscribe//订阅ZK

                         -->AbstractRegistry.subscribe

                         -->FailbackRegistry.subscribe

                           -->doSubscribe(url, listener)// 向服务器端发送订阅请求

                             -->ZookeeperRegistry.doSubscribe

                               -->new ChildListener()

                                 -->实现了 childChanged

                                   -->实现并执行 ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));

                                 //A

                               -->zkClient.create(path, false);//第一步:先创建持久化节点/dubbo/com.alibaba.dubbo.demo.DemoService/configurators

                               -->zkClient.addChildListener(path, zkListener)

                                 -->AbstractZookeeperClient.addChildListener

                                   //C

                                   -->createTargetChildListener(path, listener)//第三步:收到订阅后的处理,交给FailbackRegistry.notify处理

                                     -->ZkclientZookeeperClient.createTargetChildListener

                                       -->new IZkChildListener()

                                         -->实现了 handleChildChange //收到订阅后的处理

                                             -->listener.childChanged(parentPath, currentChilds);

                                             -->实现并执行ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));

                                             -->收到订阅后处理 FailbackRegistry.notify

                                   //B          

                                   -->addTargetChildListener(path, targetListener)////第二步

                                     -->ZkclientZookeeperClient.addTargetChildListener

                                       -->client.subscribeChildChanges(path, listener)//第二步:启动加入订阅/dubbo/com.alibaba.dubbo.demo.DemoService/configurators

                       

                       -->notify(url, listener, urls)

                         -->FailbackRegistry.notify

                           -->doNotify(url, listener, urls);

                             -->AbstractRegistry.notify

                               -->saveProperties(url);//把服务端的注册url信息更新到C:\Users\bobo\.dubbo\dubbo-registry-192.168.48.117.cache

                                 -->registryCacheExecutor.execute(new SaveProperties(version));//采用线程池来处理

                               -->listener.notify(categoryList)

                                 -->RegistryProtocol.notify

                                   -->RegistryProtocol.this.getProviderUrl(originInvoker)//通过invoker的url 获取 providerUrl的地址

                                       

相关文章
|
安全 算法 网络协议
解析:HTTPS通过SSL/TLS证书加密的原理与逻辑
HTTPS通过SSL/TLS证书加密,结合对称与非对称加密及数字证书验证实现安全通信。首先,服务器发送含公钥的数字证书,客户端验证其合法性后生成随机数并用公钥加密发送给服务器,双方据此生成相同的对称密钥。后续通信使用对称加密确保高效性和安全性。同时,数字证书验证服务器身份,防止中间人攻击;哈希算法和数字签名确保数据完整性,防止篡改。整个流程保障了身份认证、数据加密和完整性保护。
|
弹性计算 运维 安全
优化管理与服务:操作系统控制平台的订阅功能解析
本文介绍了如何通过操作系统控制平台提升系统效率,优化资源利用。首先,通过阿里云官方平台开通服务并安装SysOM组件,体验操作系统控制平台的功能。接着,详细讲解了订阅管理功能,包括创建订阅、查看和管理ECS实例的私有YUM仓库权限。订阅私有YUM仓库能够集中管理软件包版本、提升安全性,并提供灵活的配置选项。最后总结指出,使用阿里云的订阅和私有YUM仓库功能,可以提高系统可靠性和运维效率,确保业务顺畅运行。
|
网络协议 安全 Devops
Infoblox DDI (NIOS) 9.0 - DNS、DHCP 和 IPAM (DDI) 核心网络服务管理
Infoblox DDI (NIOS) 9.0 - DNS、DHCP 和 IPAM (DDI) 核心网络服务管理
573 4
|
机器学习/深度学习 算法 数据挖掘
解析静态代理IP改善游戏体验的原理
静态代理IP通过提高网络稳定性和降低延迟,优化游戏体验。具体表现在加快游戏网络速度、实时玩家数据分析、优化游戏设计、简化更新流程、维护网络稳定性、提高连接可靠性、支持地区特性及提升访问速度等方面,确保更流畅、高效的游戏体验。
362 22
解析静态代理IP改善游戏体验的原理
|
机器学习/深度学习 数据可视化 PyTorch
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
915 7
深入解析图神经网络注意力机制:数学原理与可视化实现
|
编解码 缓存 Prometheus
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
本期内容为「ximagine」频道《显示器测试流程》的规范及标准,我们主要使用Calman、DisplayCAL、i1Profiler等软件及CA410、Spyder X、i1Pro 2等设备,是我们目前制作内容数据的重要来源,我们深知所做的仍是比较表面的活儿,和工程师、科研人员相比有着不小的差距,测试并不复杂,但是相当繁琐,收集整理测试无不花费大量时间精力,内容不完善或者有错误的地方,希望大佬指出我们好改进!
1272 16
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
|
机器学习/深度学习 缓存 自然语言处理
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
Tiktokenizer 是一款现代分词工具,旨在高效、智能地将文本转换为机器可处理的离散单元(token)。它不仅超越了传统的空格分割和正则表达式匹配方法,还结合了上下文感知能力,适应复杂语言结构。Tiktokenizer 的核心特性包括自适应 token 分割、高效编码能力和出色的可扩展性,使其适用于从聊天机器人到大规模文本分析等多种应用场景。通过模块化设计,Tiktokenizer 确保了代码的可重用性和维护性,并在分词精度、处理效率和灵活性方面表现出色。此外,它支持多语言处理、表情符号识别和领域特定文本处理,能够应对各种复杂的文本输入需求。
1610 6
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
|
传感器 人工智能 监控
反向寻车系统怎么做?基本原理与系统组成解析
本文通过反向寻车系统的核心组成部分与技术分析,阐述反向寻车系统的工作原理,适用于适用于商场停车场、医院停车场及火车站停车场等。如需获取智慧停车场反向寻车技术方案前往文章最下方获取,如有项目合作及技术交流欢迎私信作者。
1078 2
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
2387 12
|
开发框架 监控 JavaScript
解锁鸿蒙装饰器:应用、原理与优势全解析
ArkTS提供了多维度的状态管理机制。在UI开发框架中,与UI相关联的数据可以在组件内使用,也可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,还可以在应用全局范围内传递或跨设备传递。
486 2

推荐镜像

更多
  • DNS