当前位置: 首页 > news >正文

辽宁网络科技有限公司衡水seo营销

辽宁网络科技有限公司,衡水seo营销,房地产图文制作网站,做内贸现在一般都通过哪些网站本文来自 Apache Seata官方文档#xff0c;欢迎访问官网#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档#xff0c;欢迎访问官网#xff0c;查看更多深度文章。 Apache Seata应用侧启动过程剖析——注册中心与配置中心模块 前言 在Seata的应用侧#xf…本文来自 Apache Seata官方文档欢迎访问官网查看更多深度文章。 本文来自 Apache Seata官方文档欢迎访问官网查看更多深度文章。 Apache Seata应用侧启动过程剖析——注册中心与配置中心模块 前言 在Seata的应用侧RM、TM启动过程中首先要做的就是与协调器侧TC建立通信这是Seata能够完成分布式事务协调的前提那么Seata在完成应用侧初始化以及与TC建立连接的过程中是如何找到TC事务协调器的集群和地址的又是如何从配置模块中获取各种配置信息的呢这正是本文要探究的重点。 给个限定 Seata作为一款中间件级的底层组件是很谨慎引入第三方框架具体实现的感兴趣的同学可以深入了解下Seata的SPI机制看看Seata是如何通过大量扩展点Extension来将依赖组件的具体实现倒置出去转而依赖抽象接口的同时Seata为了更好地融入微服务、云原生等流行架构所衍生出来的生态中也基于SPI机制对多款主流的微服务框架、注册中心、配置中心以及Java开发框架界“扛把子”——SpringBoot等做了主动集成在保证微内核架构、松耦合、可扩展的同时又可以很好地与各类组件“打成一片”使得采用了各种技术栈的环境都可以比较方便地引入Seata。 本文为了贴近大家刚引入Seata试用时的场景在以下介绍中选择应用侧的限定条件如下使用File文件作为配置中心与注册中心并基于SpringBoot启动。 有了这个限定条件接下来就让我们深入Seata源码一探究竟吧。 多模块交替协作的RM/TM初始化过程 在 Seata客户端启动过程剖析一中我们分析了Seata应用侧TM与RM的初始化、以及应用侧如何创建Netty Channel并向TC Server发送注册请求的过程。除此之外在RM初始化过程中Seata的其他多个模块注册中心、配置中心、负载均衡也都纷纷登场相互协作共同完成了连接TC Server的过程。 当执行Client重连TC Server的方法NettyClientChannelManager.Channreconnect()时首先需要根据当前的事务分组获取可用的TC Server地址列表 /*** NettyClientChannelManager.reconnect()* Reconnect to remote server of current transaction service group.** param transactionServiceGroup transaction service group*/void reconnect(String transactionServiceGroup) {ListString availList null;try {//从注册中心中获取可用的TC Server地址availList getAvailServerList(transactionServiceGroup);} catch (Exception e) {LOGGER.error(Failed to get available servers: {}, e.getMessage(), e);return;}//以下代码略}关于事务分组的详细概念介绍大家可以参考官方文档事务分组介绍。这里简单介绍一下: 每个Seata应用侧的RM、TM都具有一个事务分组名每个Seata协调器侧的TC都具有一个集群名和地址 应用侧连接协调器侧时经历如下两步通过事务分组的名称从配置中获取到该应用侧对应的TC集群名通过集群名称可以从注册中心中获取TC集群的地址列表 以上概念、关系与过程如下图所示 从注册中心获取TC Server集群地址 了解RM/TC连接TC时涉及的主要概念与步骤后我们继续探究getAvailServerList方法 private ListString getAvailServerList(String transactionServiceGroup) throws Exception {//① 使用注册中心工厂获取注册中心实例//② 调用注册中心的查找方法lookUp()根据事务分组名称获取TC集群中可用Server的地址列表ListInetSocketAddress availInetSocketAddressList RegistryFactory.getInstance().lookup(transactionServiceGroup);if (CollectionUtils.isEmpty(availInetSocketAddressList)) {return Collections.emptyList();}return availInetSocketAddressList.stream().map(NetUtil::toStringAddress).collect(Collectors.toList());}用哪个注册中心Seata元配置文件给出答案 上面已提到Seata支持多种注册中心的实现那么Seata首先需要从一个地方先获取到“注册中心的类型”这个信息。 从哪里获取呢Seata设计了一个“配置文件”用于存放其框架内所用组件的一些基本信息我更愿意称这个配置文件为 『元配置文件』这是因为它包含的信息其实是“配置的配置”也即“元”的概念大家可以对比数据库表中的信息和数据库表本身结构的信息表数据和表元数据来理解。 我们可以把注册中心、配置中心中的信息都看做是配置信息本身而这些配置信息的配置是什么这些信息就包含在Seata的元配置文件中。实际上『元配置文件』中只包含两类信息 一是注册中心的类型registry.type以及该类型注册中心的一些基本信息比如当注册中心类型为文件时元配置文件中存放了文件的名字信息当注册中心类型是Nacos时元配置文件中则存放着Nacos的地址、命名空间、集群名等信息二是配置中心的类型config.type以及该类型配置中心的一些基本信息比如当配置中心为文件时元配置文件中存放了文件的名字信息当注册中心类型为Consul时元配置文件中存放了Consul的地址信息 Seata的元配置文件支持Yaml、Properties等多种格式而且可以集成到SpringBoot的application.yaml文件中使用seata-spring-boot-starter即可方便与SpringBoot集成。 Seata中自带的默认元配置文件是registry.conf当我们采用文件作为注册与配置中心时registry.conf中的内容设置如下 registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype filefile {name file.conf} }config {# file、nacos 、apollo、zk、consul、etcd3type filefile {name file.conf} }在如下源码中我们可以发现Seata使用的注册中心的类型是从ConfigurationFactory.CURRENT_FILE_INSTANCE中获取的而这个CURRENT_FILE_INSTANCE就是我们所说的Seata元配置文件的实例 //在getInstance()中调用buildRegistryService构建具体的注册中心实例public static RegistryService getInstance() {if (instance null) {synchronized (RegistryFactory.class) {if (instance null) {instance buildRegistryService();}}}return instance;}private static RegistryService buildRegistryService() {RegistryType registryType;//获取注册中心类型String registryTypeName ConfigurationFactory.CURRENT_FILE_INSTANCE.getConfig(ConfigurationKeys.FILE_ROOT_REGISTRY ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR ConfigurationKeys.FILE_ROOT_TYPE);try {registryType RegistryType.getType(registryTypeName);} catch (Exception exx) {throw new NotSupportYetException(not support registry type: registryTypeName);}if (RegistryType.File registryType) {return FileRegistryServiceImpl.getInstance();} else {//根据注册中心类型使用SPI的方式加载注册中心的实例return EnhancedServiceLoader.load(RegistryProvider.class, Objects.requireNonNull(registryType).name()).provide();}}我们来看一下元配置文件的初始化过程当首次获取静态字段CURRENT_FILE_INSTANCE时触发ConfigurationFactory类的初始化 //ConfigurationFactory类的静态块static {load();}/*** load()方法中加载Seata的元配置文件*/ private static void load() {//元配置文件的名称支持通过系统变量、环境变量扩展String seataConfigName System.getProperty(SYSTEM_PROPERTY_SEATA_CONFIG_NAME);if (seataConfigName null) {seataConfigName System.getenv(ENV_SEATA_CONFIG_NAME);}if (seataConfigName null) {seataConfigName REGISTRY_CONF_DEFAULT;}String envValue System.getProperty(ENV_PROPERTY_KEY);if (envValue null) {envValue System.getenv(ENV_SYSTEM_KEY);}//根据元配置文件名称创建一个实现了Configuration接口的文件配置实例Configuration configuration (envValue null) ? new FileConfiguration(seataConfigName,false) : new FileConfiguration(seataConfigName - envValue, false);Configuration extConfiguration null;//通过SPI加载来判断是否存在扩展配置提供者//当应用侧使用seata-spring-boot-starer时将通过SpringBootConfigurationProvider作为扩展配置提供者这时当获取元配置项时将不再从file.conf默认中获取而是从application.properties/application.yaml中获取try {//通过ExtConfigurationProvider的provide方法将原有的Configuration实例替换为扩展配置的实例extConfiguration EnhancedServiceLoader.load(ExtConfigurationProvider.class).provide(configuration);if (LOGGER.isInfoEnabled()) {LOGGER.info(load Configuration:{}, extConfiguration null ? configuration.getClass().getSimpleName(): extConfiguration.getClass().getSimpleName());}} catch (EnhancedServiceNotFoundException ignore) {} catch (Exception e) {LOGGER.error(failed to load extConfiguration:{}, e.getMessage(), e);}//存在扩展配置则返回扩展配置实例否则返回文件配置实例CURRENT_FILE_INSTANCE extConfiguration null ? configuration : extConfiguration;}load()方法的调用序列图如下 上面的序列图中大家可以关注以下几点 Seata元配置文件名称支持扩展Seata元配置文件后缀支持3种后缀分别为yaml/properties/conf在创建元配置文件实例时会依次尝试匹配Seata中配置能力相关的顶级接口为Configuration各种配置中心均需实现此接口Seata的元配置文件就是使用FileConfiguration文件类型的配置中心实现了此接口 /*** Seata配置能力接口* packageio.seata.config*/public interface Configuration {/*** Gets short.** param dataId the data id* param defaultValue the default value* param timeoutMills the timeout mills* return the short*/short getShort(String dataId, int defaultValue, long timeoutMills);//以下内容略主要能力为配置的增删改查 }Seata提供了一个类型为ExtConfigurationProvider的扩展点开放了对配置具体实现的扩展能力它具有一个provide()方法接收原有的Configuration返回一个全新的Configuration此接口方法的形式决定了一般可以采用静态代理、动态代理、装饰器等设计模式来实现此方法实现对原有Configuration的增强 /*** Seata扩展配置提供者接口* packageio.seata.config*/ public interface ExtConfigurationProvider {/*** provide a AbstractConfiguration implementation instance* param originalConfiguration* return configuration*/Configuration provide(Configuration originalConfiguration); }当应用侧基于seata-seata-spring-boot-starter启动时将采用『SpringBootConfigurationProvider』作为扩展配置提供者在其provide方法中使用动态字节码生成CGLIB的方式为『FileConfiguration』实例创建了一个动态代理类拦截了所有以get开头的方法来从application.properties/application.yaml中获取元配置项。 关于SpringBootConfigurationProvider类本文只说明下实现思路不再展开分析源码这也仅是ExtConfigurationProvider接口的一种实现方式从Configuration可扩展、可替换的角度来看Seata正是通过ExtConfigurationProvider这样一个扩展点为多种配置的实现提供了一个广阔的舞台允许配置的多种实现与接入方案。 经历过上述加载流程后如果我们没有扩展配置提供者我们将从Seata元配置文件中获取到注册中心的类型为file同时创建了一个文件注册中心实例FileRegistryServiceImpl 从注册中心获取TC Server地址 获取注册中心的实例后需要执行lookup()方法RegistryFactory.getInstance().lookup(transactionServiceGroup)FileRegistryServiceImpl.lookup()的实现如下 /*** 根据事务分组名称获取TC Server可用地址列表* packageio.seata.discovery.registry* classFileRegistryServiceImpl*/Overridepublic ListInetSocketAddress lookup(String key) throws Exception {//获取TC Server集群名称String clusterName getServiceGroup(key);if (clusterName null) {return null;}//从配置中心中获取TC集群中所有可用的Server地址String endpointStr CONFIG.getConfig(PREFIX_SERVICE_ROOT CONFIG_SPLIT_CHAR clusterName POSTFIX_GROUPLIST);if (StringUtils.isNullOrEmpty(endpointStr)) {throw new IllegalArgumentException(clusterName POSTFIX_GROUPLIST is required);}//将地址封装为InetSocketAddress并返回String[] endpoints endpointStr.split(ENDPOINT_SPLIT_CHAR);ListInetSocketAddress inetSocketAddresses new ArrayList();for (String endpoint : endpoints) {String[] ipAndPort endpoint.split(IP_PORT_SPLIT_CHAR);if (ipAndPort.length ! 2) {throw new IllegalArgumentException(endpoint format should like ip:port);}inetSocketAddresses.add(new InetSocketAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1])));}return inetSocketAddresses;}/*** 注册中心接口中的default方法* packageio.seata.discovery.registry* classRegistryService*/default String getServiceGroup(String key) {key PREFIX_SERVICE_ROOT CONFIG_SPLIT_CHAR PREFIX_SERVICE_MAPPING key;//在配置缓存中添加事务分组名称变化监听事件if (!SERVICE_GROUP_NAME.contains(key)) {ConfigurationCache.addConfigListener(key);SERVICE_GROUP_NAME.add(key);}//从配置中心中获取事务分组对应的TC集群名称return ConfigurationFactory.getInstance().getConfig(key);}可以看到代码逻辑与第一节中图Seata事务分组与建立连接的关系中的流程相符合 这时注册中心将需要配置中心的协助来获取事务分组对应的集群名称、并查找集群中可用的服务地址。 从配置中心获取TC集群名称 配置中心的初始化 配置中心的初始化在ConfigurationFactory.buildConfiguration()与注册中心的初始化流程类似都是先从元配置文件中获取配置中心的类型等信息然后初始化一个具体的配置中心实例有了之前的分析基础这里不再赘述。 获取配置项的值 上方代码段的两个方法*FileRegistryServiceImpl.lookup()以及RegistryService.getServiceGroup()*中都从配置中心中获取的配置项的值 lookup()需要由具体的注册中心实现使用文件作为注册中心其实是一种直连TC Server的情况其特殊点在于TC Server的地址是写死在配置中的的正常应存于注册中心中因此FileRegistryServiceImpl.lookup()方法是通过配置中心获取的TC集群中Server的地址信息getServiceGroup()是RegistryServer接口中的default方法即所有注册中心的公共实现Seata中任何一种注册中心都需要通过配置中心来根据事务分组名称来获取TC集群名称 负载均衡 经过上述环节配置中心、注册中心的协作现在我们已经获取到了当前应用侧所有可用的TC Server地址那么在发送真正的请求之前还需要通过特定的负载均衡策略选择一个TC Server地址这部分源码比较简单就不带着大家分析了。 关于负载均衡的源码大家可以阅读AbstractNettyRemotingClient.doSelect()因本文分析的代码是RMClient/TMClient的重连方法此方法中所有获取到的Server地址都会通过遍历依次连接重连因此这里不需要再做负载均衡。 以上就是Seata应用侧在启动过程中注册中心与配置中心这两个关键模块之间的协作关系与工作流程欢迎共同探讨、学习 后记本文及其上篇 Seata客户端启动过程剖析一是本人撰写的首批技术博客将上手Seata时个人认为Seata中较为复杂、需要研究和弄通的部分源码进行了分析和记录。 在此欢迎各位读者提出各种改进建议谢谢
http://www.w-s-a.com/news/162897/

相关文章:

  • app手机网站建设黄网站建设定制开发服务
  • 百度网盘app下载徐州优化网站建设
  • 附近网站电脑培训班展台设计方案介绍
  • 河南便宜网站建设价格低上海高端室内设计
  • 保险网站有哪些平台wordpress会员vip购买扩展
  • 网站怎么做图片转换广州车陂网站建设公司
  • 下载flash网站网站设计书的结构
  • 水利建设公共服务平台网站放心网络营销定制
  • 设计网站过程wordpress+分页静态
  • 临海网站制作好了如何上线如果安装wordpress
  • 长沙 学校网站建设网站制作价格上海
  • 九江网站推广徽hyhyk1国家住房部和城乡建设部 网站首页
  • 阿克苏网站建设咨询动漫设计与制作属于什么大类
  • 网站编辑做多久可以升职wordpress版权修改
  • 网站开发维护成本计算国外外贸平台
  • 简单的招聘网站怎么做购物网站功能报价
  • 哪个网站做中高端衣服建设自己网站的流程
  • 网站建设概况做网站的是怎么赚钱的
  • 网站发布信息的基本流程现在都不用dw做网站了吗
  • 赣州热门网站深圳龙岗做网站的公司
  • 中国最大的建站平台广告传媒公司取名
  • 深圳网站设计公司专业吗学动漫设计后悔死了
  • 企业网站形象建设网站开发入职转正申请书
  • 网站设计步骤济南建设网中标公告
  • 石佛营网站建设wordpress关健词
  • 您的网站空间即将过期建站 discuz
  • 上海简站商贸有限公司福州哪家专业网站设计制作最好
  • 博客网站开发流程苏州专业做网站的公司哪家好
  • 四川手机网站建设西安 网站 高端 公司
  • 织梦大气绿色大气农业能源化工机械产品企业网站源码模版建筑工程知识零基础