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) {// 注册中心URLURL 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本地接口监听网络请求。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML+JavaScript-03

JavaScript函数 定义函数的格式 JavaScript 函数是通过 function 关键词定义的。 function sum(a, b){//函数体return a b;//返回值为a、b的和 }函数的调用 调用函数时直接书写函数名即可 function show(){alert("函数show被调用"); } show();函数的相互调用 …

使用Docker部署Apache Superset结合内网穿透实现远程访问本地服务

文章目录 前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透&#xff0c;实现公网访问3. 设置固定连接公网地址 前言 Superset是一款由中国知名科技公司开源的“现代化的…

PSEUDO-LIDAR++:自动驾驶中 3D 目标检测的精确深度

论文地址&#xff1a;PSEUDO-LIDAR: ACCURATE DEPTH FOR 3D OBJECT DETECTION IN AUTONOMOUS DRIVING 论文代码&#xff1a;https://github.com/mileyan/Pseudo_Lidar_V2 摘要 3D 检测汽车和行人等物体在自动驾驶中发挥着不可或缺的作用。现有方法很大程度上依赖昂贵的激光雷…

华为数通方向HCIP-DataCom H12-831题库(判断题:81-100)

第81题 基本QinQ能根据业务种类选择外层Tag封装的方式 正确 错误 答案: 错误 解析: 基本QinQ是基于端口方式实现的,不能根据业务种类选择外层TAG封装的方式。 第82题 display interface GE0/0/0-次,发现Total Error计数(该接口物理层的错误报文总数目)不是此时可以断定当前…

登录页面(附源码)

特色&#xff1a; 点击登录之后卡片翻转效果 话不多说&#xff0c;看展示。 还在等什么&#xff0c;赶快白嫖起来吧 HTML文件 <div id"window" style"display: none"><div class"page page-front"><div class"page-content&…

SCCB接口

文章目录 概述引脚传输时序起始/结束信号三线模式两线模式 传输周期3阶段写传输周期2阶段写传输周期2阶段读传输周期阶段一 ID Address阶段二 子地址/读数据阶段三 写数据 SCCB与IIC区别未完待续(还有代码&#xff09;... 概述 SCCB&#xff08;Serial Camera Control Bus&…

aspose-cells-20.7.jar 去除水印及次数限制

1.使用 jd-gui.exe 反编译查看&#xff0c;直接搜索 License 1.修改 public static boolean isLicenseSet() {return (a ! null);}改成 public static boolean isLicenseSet() {return true;}2.修改 public void setLicense(InputStream stream) {Document document null;if (…

【EI会议征稿通知】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于20…

SpringMVC:拦截器

一般我们会做一些统一的操作这个时候我们需要使用springmvc提供的拦截器&#xff0c;例如token的验证&#xff0c;字段必填的操作&#xff0c;接口超时判断&#xff0c;签名验证&#xff0c;字段加密等操作&#xff0c;所以我们需要了解执行先后顺序。 我们来简单介绍下实现过程…

第6章-路由器、交换机及其操作系统介绍

目录 1. 路由器与交换机的作用与特点 1.1. 路由器 1.2. 交换机 1.3. 路由交换 2. H3C路由器与交换机介绍 3. H3C网络设备操作系统Comware 1. 路由器与交换机的作用与特点 1.1. 路由器 1、定义&#xff1a;路由器&#xff08;Router&#xff09;是连接两个或多个网络的硬…

穿越Flink的时间隧道:解锁实时数据之窗,掌握流处理之巅

目录 Flink中的时间和窗口 1时间语义 1.1Flink中的时间语义 1.1.1处理时间 1.1.2事件时间 1.2那种时间语义更重要 2 水位线 2.1 事件时间和窗口 2.2 什么是水位线 2.3 如何生成水位线 2.3.1使用WatermarkGenerator 2.3.2使用SourceFunction 2.4 水位线的传递 2.5 水位…

R语言中数据框是什么?

在数据分析过程中离不开表格&#xff0c;通常使用Excel来做数据分析&#xff0c;行和列用来存放不同的数据&#xff0c;表格能清晰直观的展示数据&#xff0c;而且可以将多张表组合联系起来&#xff0c;这种不约而同的规范也同样适用于R语言。 R语言中的数据框&#xff08;Data…

2023年度环境电器行业数据分析(洗地机、扫地机器人、吸尘器等)

在家电行业整体消费不振的环境下&#xff0c;环境电器市场也受到影响&#xff0c;2023年度市场大盘销售呈下滑趋势。根据鲸参谋平台的数据显示&#xff0c;2023年京东平台环境电器市场的销量累计约7100万&#xff0c;同比下滑约12%&#xff1b;销售额约360亿&#xff0c;同比下…

【图形学】实现二维几何变换

二维点类 class CPoint2 { public:CPoint2();CPoint2(double x, double y);~CPoint2();friend CPoint2 operator (const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator -(const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator *(const…

云原生 - 微信小程序 COS 对象存储图片缓存强制更新解决方案

问题描述 遇到一个这样的情况&#xff1a;在微信小程序里图片缓存十分麻烦&#xff0c;网上很多说在腾讯云里的 COS 存储对象服务里设置对应的图片缓存&#xff08;Header 头 Cache-Contorl&#xff09;&#xff0c;说实话真不好用&#xff0c;一会儿生效&#xff0c;一会儿没…

excel学习1

直接ctrl cctrl v会报错位移选择粘贴时用123那个数字粘贴而不是ctrl V 只要结果不要公式 上面复制的为数值这里是复制的公式他们两个不一样 这个方法太麻烦了直接用格式刷&#xff0c;选择一个区域一个单元格&#xff0c;不要选择多个一刷就出来了 第一个计算后向下拖就行了&…

FastDFS分布式文件存储

为什么会有分布式文件系统&#xff1f; 分布式文件系统是面对互联网的需求而产生。因为互联网时代要对海量数据进行存储。很显然靠简单的增加硬盘个数已经满足不了我们的要求。因为硬盘传输速度有限但是数据在急剧增长&#xff0c;另外我们还要要做好数据备份、数据安全等。采用…

Git的安装与配置

目录 前言 Linux-centos&#xff1a;下安装 Linux_ubuntu下安装 创建Git本地仓库 配置用户名和Email 前言 Git是一种版本控制器&#xff0c;能够让我们了解一个文件的历史&#xff0c;以及它的发展过程。通俗的将就是可以记录一个工程的每一次改动和版本迭代的一个管理系统…

【vscode】6、调试 shell

文章目录 经常在 IDE 下使用 高级语言后&#xff0c;往往并不习惯 shell 编程&#xff0c;因为没有酷炫的界面。但现在 vscode 可以很方便的调试 shell 脚本。 配置方法如下&#xff1a; vscode 下载 Bash Debug 插件 mac 升级 bash 版本&#xff08;因为此 vscode 插件需要 b…

蓝桥杯重要知识点和赛题直通车

<蓝桥杯软件赛>零基础备赛20周 第 1周(2023-10-23): 蓝桥杯软件赛介绍官方链接零基础能得奖吗&#xff1f; 第 2周(2023-10-30): 常考知识点蓝桥杯怎么判题备赛计划 第 3周(2023-11-06): 填空题&#xff08;分数少但越来越不好做&#xff09; 第 4周(2023-11-13): &#…