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,一经查实,立即删除!

相关文章

js之执行上下文和作用域

定义 变量和函数的上下文决定了它们可以访问那些数据&#xff0c;以及它们的行为 每个上下文都有一个关联的变量对象&#xff0c;而这个上下文中定义的所有变量和函数都在存在于这个变量对象之上 上下文再其所以代码都执行完毕之后会被销毁&#xff0c;包括定义在它上面的所有…

研究生开题报告撰写:文言一心VSChatgpt3.5

文言一心 问&#xff1a;我是一名研二学生&#xff0c;请帮我生成一份研究生毕设开题答辩ppt框架。 答&#xff1a;好的&#xff0c;以下是一份研究生毕设开题答辩PPT的框架&#xff0c;供您参考&#xff1a; 幻灯片1&#xff1a;封面页 标题&#xff1a;研究生毕设开题答辩…

大数据学习之Flink、10分钟了解Flink的核心组件以及它们的工作原理

第一章、Flink的容错机制 第二章、Flink核心组件和工作原理 第三章、Flink的恢复策略 第四章、Flink容错机制的注意事项 第五章、Flink的容错机制与其他框架的容错机制相比较 目录 第二章、Flink核心组件和工作原理 Ⅰ、核心组件 1. Checkpoint组件&#xff1a; 2. Sav…

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 检测汽车和行人等物体在自动驾驶中发挥着不可或缺的作用。现有方法很大程度上依赖昂贵的激光雷…

ChatGPT Claude Bard 生成式 AI 免责声明

ChatGPT Claude Bard 生成式 AI 免责声明 ChatGPT can make mistakes. Consider checking important information.Claude.ai is in beta release and may display incorrect or harmful informationBard may display inaccurate info, including about people, so double-check…

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

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

【Spring Boot 3】【Redis】集成Redisson

【Spring Boot 3】【Redis】集成Redisson 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花…

CentOS7 开启防火墙及开放指定端口

CentOS7 开启防火墙及开放指定端口 查看防火墙状态systemctl status firewalld启动防火墙systemctl start firewalld停止防火墙systemctl stop firewalld查看防火墙已经开放的端口firewall-cmd --list-port添加开放指定防火墙firewall-cmd --zonepublic --add-port这里是需要开…

登录页面(附源码)

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

一些 AI 机构

文章目录 OpenAITHUDMMetaAITIIStability AINousResearch OpenAI hf : https://huggingface.co/openai 官网&#xff1a;https://openai.com THUDM 清华大学 KEG 和 THUDM 团队 Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University hf : https://h…

SCCB接口

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

ElementUI简介以及相关操作

ElementUI是一套基于Vue.js的桌面端组件库&#xff0c;提供了丰富的组件帮助开发人员快速构建功能强大、风格统一的页面。以下是ElementUI的简介以及相关操作&#xff1a; 简介&#xff1a;ElementUI是一套为开发者、设计师和产品经理准备的基于Vue 2.0的桌面端组件库&#xff…

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 水位…

bvh转fbx python实战代码

目录 参数含义: bvh转fbx python实战代码 参数含义: 参考: Export Scene Operators — Blender Python API filepath (string, (optional, never None)) – File Path, Filepath used for exporting the file check_existing (boolean