dubbo:服务暴露

在这里插入图片描述

节点角色说明:
Provider:暴露服务的服务提供方。
Consumer::调用远程服务的服务消费方。
Registry:服务注册与发现的注册中心。
Monitor:统计服务的调用次调和调用时间的监控中心。
Container:服务运行容器。
调用关系说明:
0.服务容器负责启动,加载,运行服务提供者。
1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送次统计数据到监控中心。

暴露流程:

首先,服务器端(服务提供者)在框架启动时,会初始化服务实例,通过Proxy组件调 用具体协议(Protocol ),把服务端要暴露的接口封装成Invoker (真实类型是 AbstractProxylnvoker ,然后转换成Exporter,这个时候框架会打开服务端口等并记录服务实例 到内存中,最后通过Registry把服务元数据注册到注册中心。这就是服务端(服务提供者)整 个接口暴露的过程。

Proxy组件:我们知道,Dubbo中只需要引用一个接口就可以调用远程的服务,并且
只需要像调用本地方法一样调用即可。其实是Dubbo框架为我们生成了代理类,调用
的方法其实是Proxy组件生成的代理方法,会自动发起远程/本地调用,并返回结果,
整个过程对用户完全透明。
• Protocol:顾名思义,协议就是对数据格式的一种约定。它可以把我们对接口的配置,
根据不同的协议转换成不同的Invoker对象。例如:用DubboProtocol可以把XML文
件中一个远程接口的配置转换成一个Dubbolnvoker。
• Exporter:用于暴露到注册中心的对象,它的内部属性持有了 Invoker对象,我们可以
认为它在Invoker上包了 一层。
• Registry:把Exporter注册到注册中心。

使用:

提供者(provider)服务提供者需要提供xxx-api.jar,供消费者引入并使用其中包含的接口,同时自身引入并实现相应的接口

provider暴露服务:

在dubbo.xml中的xsl:schemalocation中加入

http://code.alibabatech.com/schema/dubbo
http://code.allbabatech.com/schema/dubbo/dubbo.xsd">

并注册

<dubbo:registry address=“$(dubbo.registry.address)”
protocol="zookeeper"group="S(dubbo.group.smart_pnr)"id="tts_smart_pnr/>

在dubbo-service.xml:

<dubbo:service interface="com.gunar.flight.tts.smart.pnr.api.ISmartPnrService"ref=“iSmartPnrServicelmpl”
version-"1.0.0"timeout-"30000"registry-“tts_smart_pnr"cluster"fallfast”/>

消费者:

引入api.jar

<dubbo:registry address=“ d u b b o . r e g i s t r y . a d d r e s s ” p r o t o c o l = “ z o o k e e p e r ” g r o u p = “ {dubbo.registry.address}” protocol=“zookeeper” group=“ dubbo.registry.addressprotocol=zookeepergroup={dubbo.group.smart_pnr}” id=“tts_smart_pnr”/>

<dubbo:service interface=“com.qunar.flight.tts.smart.pnr.api.ISmartPnrService” ref=“iSmartPnrServiceImpl”

                      version=“1.0.0” timeout=“30000” registry=“tts_smart_pnr” cluster=“failfast”/>

<dubbo:reference id=“iSmartPnrService”

             interface="com.qunar.flight.tts.smart.pnr.api.ISmartPnrService" 

           registry="tts_smart_pnr" 

           timeout="5000" 

           check="false" 

           cluster="failfast" 

           version="1.0.0">

<dubbo:method name=“validateOnpay” timeout=“6000”/>

address:dubbo注册的zk的集群

protocol:dubbo注册使用的协议

group:dubbo服务的所属组

Interface:所提供的服务

ref:对应的实现类

version:提供的dubbo服务的版本号

timeout:服务提供者的超时时间

cluster:重试机制,常用的有failfast、failover(默认3次,可以配合retries使用自定义重试次数)

服务暴露流程

首先会通过initialize()方法完成初始化,装配各种Config对象,为后续的服务暴露和引用准备好环境。

ServiceConfig对象就是Dubbo对服务的描述对象,服务暴露的逻辑都在ServiceConfig#export()里面,Dubbo暴露服务也就是遍历所有的ServiceConfig,挨个进行暴露。

ServiceConfig描述了对外提供的服务,ref属性引用了具体的服务实现对象,当Provider接收到Consumer发起的RPC调用时,会交给ref执行,但是Dubbo不会直接使用ref,因为不管是Provider还是Consumer,Dubbo都在向Invoker靠拢。

Invoker是本地调用、远程调用、集群调用

Dubbo服务暴露的入口在ServiceConfig#export()方法

配置的校验和更新
暴露服务
分发服务暴露事件

public synchronized void export() {
    // 检查和更新配置
    checkAndUpdateSubConfigs();
 
    if (shouldDelay()) {
        // 延迟暴露
        DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);
    } else {
        // 暴露服务
        doExport();
    }
    // 分发暴露事件
    exported();
}

其中的checkAndUpdateSubConfigs()

对ServiceConfig对象做一些配置的校验和自动更新。例如使用ProviderConfig的全局默认配置、将protocolIds转换成ProtocolConfig对象、自身的属性按照优先级进行刷新等等。配置更新完了,接下来就是做服务暴露的前置Check,例如注册中心是否有效、ref对象是否符合要求等等。

private void checkAndUpdateSubConfigs() {
    // 使用ProviderConfig默认配置
    completeCompoundConfigs();
    // ProviderConfig不存在则自动创建
    checkDefault();
    // protocolIds转换
    checkProtocol();
     
    if (!isOnlyInJvm()) {
        // 服务注册,还要检查配置中心
        checkRegistry();
    }
    // 自身属性根据优先级刷新
    this.refresh();
    checkStubAndLocal(interfaceClass);
    ConfigValidationUtils.checkMock(interfaceClass, this);
    ConfigValidationUtils.validateServiceConfig(this);
    postProcessConfig();
    代码有精简...
}

doExport()

ServiceRepository repository = ApplicationModel.getServiceRepository();
// 注册Service
ServiceDescriptor serviceDescriptor = repository.registerService(getInterfaceClass());
// 注册Provider
repository.registerProvider(getUniqueServiceName(),ref,serviceDescriptor,this,serviceMetadata);
 
接下来,获取当前服务需要注册到哪些注册中心,加载对应的URL// 加载配置中心URL
List<URL> registryURLs = ConfigValidationUtils.loadRegistries(this, true);Check那一步,就已经解析了服务需要通过哪些协议进行暴露,所以接下来会遍历protocols,进行单协议多注册中心暴露。
 
for (ProtocolConfig protocolConfig : protocols) {
    String pathKey = URL.buildKey(getContextPath(protocolConfig)
                                  .map(p -> p + "/" + path)
                                  .orElse(path), group, version);
    repository.registerService(pathKey, interfaceClass);
    serviceMetadata.setServiceKey(pathKey);
    // 单协议多注册中心暴露
    doExportUrlsFor1Protocol(protocolConfig, registryURLs);
}
 
服务暴露需要用到各种参数,用于构建后续的服务暴露URL,这里会使用HashMap存储。Dubbo的配置粒度是到方法级别的,对应的类是MethodConfig,如果有方法级别的配置,也需要解析到Map中。
 
// 服务暴露的各种参数,用于组装服务暴露URL
Map<String, String> map = new HashMap<String, String>();
map.put(SIDE_KEY, PROVIDER_SIDE);
// 运行时参数
ServiceConfig.appendRuntimeParameters(map);
AbstractConfig.appendParameters(map, getMetrics());
AbstractConfig.appendParameters(map, getApplication());
AbstractConfig.appendParameters(map, getModule());
......
 
参数组装完毕,解析出服务暴露的host和port,然后构建URL// 查找服务暴露的host和port
String host = findConfigedHosts(protocolConfig, registryURLs, map);
Integer port = findConfigedPorts(protocolConfig, name, map);
// 构建URL
URL url = new URL(name, host, port, getContextPath(protocolConfig).map(p -> p + "/" + path).orElse(path), map);

服务暴露的范围可以通过scope属性配置,none代表不暴露、local仅暴露到本地JVM、remote会暴露到远程。Dubbo在服务暴露前会进行判断,默认情况下会同时暴露到本地JVM和远程。

服务注册:

protected Registry getRegistry(final Invoker<?> originInvoker) {
    // 注册中心URL
    URL registryUrl = getRegistryUrl(originInvoker);
    // SPI加载Registry实现
    return registryFactory.getRegistry(registryUrl);
}
 
解析出需要注册到注册中心的URL,然后调用RegistryService#register()完成服务注册。
 
final Registry registry = getRegistry(originInvoker);
// 注册到注册中心的URL
final URL registeredProviderUrl = getUrlToRegistry(providerUrl, registryUrl);
// 是否立即注册
boolean register = providerUrl.getParameter(REGISTER_KEY, true);
if (register) {
    register(registryUrl, registeredProviderUrl);
}
 
最终操作:
public void doRegister(URL url) {
    final String serviceName = getServiceName(url);
    final Instance instance = createInstance(url);
    // 注册服务,最终调用 NamingService#registerInstance()
    execute(namingService -> namingService.registerInstance(serviceName,getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP), instance));
}

Dubbo服务暴露,先将ref封装成Invoker,Invoker会根据Consumer的Invocation参数对ref发起调用,Dubbo默认使用javassist字节码技术动态生成Wrapper类,避免了Java反射带来的性能问题。
有了Invoker就可以通过Protocol根据协议进行服务暴露,如果服务需要注册,Dubbo会改写URL协议为registry,这是个伪协议,只是在原服务暴露的基础上,增加了服务注册的功能。
在根据协议暴露服务前,还需要关注两个包装类:ProtocolFilterWrapper和ProtocolListenerWrapper,前者用于构建Filter链,后者用于服务取消暴露时触发事件。
以dubbo协议为例,除了创建DubboExporter,还会根据服务暴露的address创建ProtocolServer。Transporter是dubbo对网络传输层的抽象接口,以Netty为例,底层其实就是创建了ServerBootstrap,然后bind本地接口监听网络请求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/342575.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu上创建ftp服务器

今天在linux电脑上安装了ftp服务器&#xff0c;中间碰到不少问题&#xff0c;参照各路攻略&#xff0c;修改多次配置后终于完成了服务器搭建 1&#xff1a;安装vsftp服务器 最简答的一步&#xff0c;直接&#xff1a;apt-get install vsftp 安装完成后&#xff0c;查看版本号…

蓝桥杯(C++ 最大开支 优先队列)

优先队列&#xff1a; 蓝桥杯&#xff08;C 整数删除 优先队列 &#xff09;-CSDN博客 思路&#xff1a; 1、每个人依此选择项目&#xff0c;每个人选项目时都&#xff08;选择当下花费增加最多的项目&#xff09;&#xff0c;若项目i的门票价格为kxb&#xff0c;那么增加一个…

机器学习 | 深入理解并掌握核心概念

在如今数字化时代的浪潮下&#xff0c;机器学习已经成为人工智能领域的璀璨明星。它像一面魔镜&#xff0c;赋予计算机系统学习和改进的能力&#xff0c;让机器能够从海量数据中提取规律、预测未来&#xff0c;甚至做出智能决策。本 专栏 将带您踏上机器学习的奇妙之旅&#xf…

机器人学论文——智能施药机器人调研报告

目录 摘 要 Abstract 第一章&#xff1a;引言 1.1研究背景 1.2 研究意义 1.3文章架构 第二章&#xff1a;智能施药机器人发展现状 2.1引言 2.2 大田智能施药机器人发展现状 2.3 果园智能施药机器人发展现状 2.4 设施农业智能施药机器人发展现状 第三章&#xff1a;智能施药机器…

短视频推广方案,新品推广攻略

短视频以其生动、直观的特点吸引了大量用户&#xff0c;成为品牌塑造、产品推广的有效手段。本文将深入解读短视频推广方法&#xff0c;帮助企业在这个充满创意和活力的平台上实现产品的成功推广。 一、抓住用户注意力的前奏&#xff1a;创意内容制作 引人入胜的开篇&#xff…

打家劫舍系列(三合一)(动态规划)

本篇博客讲解一下动态规划的打家劫舍系列&#xff0c;对应的力扣题目分别是198. 打家劫舍&#xff0c;213. 打家劫舍 II&#xff0c;337. 打家劫舍 III 198. 打家劫舍&#xff1a; 题目&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的…

关于C#中的HashSet<T>与List<T>

HashSet<T> 表示值的集合。这个集合的元素是无须列表&#xff0c;同时元素不能重复。由于这个集合基于散列值&#xff0c;不能通过数组下标访问。 List<T> 表示可通过索引访问的对象的强类型列表。内部是用数组保存数据&#xff0c;不是链表。元素可重复&#xf…

【数据结构】快速排序,归并排序

快速排序 1.hoare版本 根据动图的演示&#xff0c;整理的思路如下&#xff0c; 1.定义left,right,key。key默认是左边第一个元素&#xff0c;像两个指针&#xff0c;左边找比key大的&#xff0c;右边找比k小的&#xff0c;找到的话&#xff0c;交换二者&#xff0c;往返这个过…

《移动通信原理与应用》——QAM调制解调仿真

目录 一、QAM调制与解调仿真流程图&#xff1a; 二、仿真结果&#xff1a; 三、Matlab仿真程序代码如下&#xff1a; 一、QAM调制与解调仿真流程图&#xff1a; QAM调制仿真流程图&#xff1a; QAM解调仿真流程图&#xff1a; 二、仿真结果&#xff1a; &#xff08;1&…

JOSEF约瑟 中间继电器JZ14-44Z/4 不带外罩和接线座

系列型号 JZ14-014Z/0中间继电器;JZ14-014Z/1中间继电器; JZ14-014Z/2中间继电器;JZ14-014Z/4中间继电器; JZ14-014J/0中间继电器;JZ14-014J/1中间继电器; JZ14-014J/2中间继电器;JZ14-014J/3中间继电器; JZ14-014J/4中间继电器;JZ14-140Z/0中间继电器; JZ14-140Z/1中间继…

Web06--JavaScript基础02

1、JS流程控制语句 JS与Java一样&#xff0c;也有三个流程控制语句&#xff1a; 顺序结构 选择结构 循环结构 1.1 选择结构 1.1.1 if结构 <script type"text/javascript">if (条件表达式) {代码块;} else if(条件表达式){代码块;} else {代码块;} </scr…

Flink中的容错机制

一.容错机制 在Flink中&#xff0c;有一套完整的容错机制来保证故障后的恢复&#xff0c;其中最重要的就是检查点。 1.1 检查点&#xff08;Checkpoint&#xff09; 在流处理中&#xff0c;我们可以用存档读档的思路&#xff0c;将之前某个时间点的所有状态保存下来&#xf…

MATLAB实现岭回归数学建模算法

岭回归&#xff08;Ridge Regression&#xff09;是一种线性回归的扩展&#xff0c;用于处理多重共线性&#xff08;multicollinearity&#xff09;的问题。多重共线性是指自变量之间存在高度相关性的情况&#xff0c;这可能导致线性回归模型的不稳定性和过拟合。 岭回归通过在…

风二西CTF流量题大集合-刷题笔记|基础题(4)

61.sql2 sql.pcapng flag{a3eb0ff8-e467-5036-7c9b-287f6848d5f3} 62.冰蝎2.0 swt1.pcapng flag{0867c25f69f0c62c970408ccefe29bb7} 64.gs哥斯拉流量4.0 gs.pcapng flag{0fffbfa87e5508955b397950502db0bd} 65.冰蝎web流量 webshell.pcapng flag{da2c30d9318a0d80b4bfa…

C++——IOStream

什么是IO&#xff1f; C语言和C&#xff0c;我们其实已经接触到了两个IO的概念 #include<stdio.h> #include<iostream> iostream&#xff0c;便是IO流&#xff0c;其中I表示in&#xff0c;O表示out&#xff0c;代表着用户的输入和终端的输出。在之前的C语法中&a…

【服务器】安装Docker环境

目录 &#x1f33a;【前言】 &#x1f33c;1. 打开Xshell软件 &#x1f33b;2. 安装Docker环境 ①&#xff1a;下载docker.sh脚本 ②&#xff1a;列出下载的内容 ③&#xff1a;执行一下get-docker.sh文件&#xff0c;安装docker ④&#xff1a;运行docker服务 ⑤&…

内网安全管理系统(保密管理系统)

在当今信息化的时代&#xff0c;企业的内网已经成为其核心资产的重要组成部分。 随着企业的快速发展和信息化程度的提升&#xff0c;内网安全问题日益凸显&#xff0c;如何保障内网的安全和机密信息的保密性&#xff0c;已经成为企业亟待解决的问题。 内网安全管理系统(保密管…

定时任务组件Quartz

Quartz介绍 Quartz 是一个功能丰富的开源作业调度库&#xff0c;几乎可以集成到任何 Java 应用程序中 - 从最小的独立应用程序到最大的电子商务系统。Quartz 可用于创建简单或复杂的计划&#xff0c;以执行数十、数百甚至数万个作业;其任务被定义为标准 Java 组件的作业&#x…

了解HTTP/1.1、HTTP/1.0 和 HTTP/2.0

HTTP/1.1、HTTP/1.0 和 HTTP/2.0 是超文本传输协议&#xff08;HTTP&#xff09;的三个主要版本 先解释一下什么是超文本协议 超文本传输协议&#xff08;HyperText Transfer Protocol&#xff0c;简称 HTTP&#xff09;是互联网上应用最广泛的一种网络协议。设计 HTTP 的初衷是…

STM32(--001) Win10、Win11 上的驱动安装说明

一、USB线插到 CMSIS-DAP 接口上&#xff0c;将自动识别到两个设备 ① CMSIS-DAP&#xff1a;用于烧录代码、在线硬件仿真; 在Keil里烧录&#xff0c;无需通过FlyMCU; ② USB转TTL&#xff1a;用于开发板与电脑间串口通信 &#xff0c;即USART1, TX-PA9、RX-PA10; 接口备注&a…