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

一万元做网站百度推广的步骤

一万元做网站,百度推广的步骤,嘉兴招聘网,代办公司注册地址本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 Apache Seata配置管理原理解析 说到Seata中的配置管理,大家可能会想到Seata中适配…

本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。
本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。

Apache Seata配置管理原理解析

说到Seata中的配置管理,大家可能会想到Seata中适配的各种配置中心,其实今天要说的不是这个,虽然也会简单分析Seata和各配置中心的适配过程,但主要还是讲解Seata配置管理的核心实现

Server启动流程

在讲配置中心之前,先简单介绍一下Server端的启动流程,因为这一块就涉及到配置管理的初始化,核心流程如下:

  1. 程序入口在Server#main方法中
  2. 获取port的几种形式:从容器中获取;从命令行获取;默认端口
  3. 解析命令行参数:host、port、storeMode等参数,这个过程可能涉及到配置管理的初始化
  4. Metric相关:无关紧要,跳过
  5. NettyServer初始化
  6. 核心控制器初始化:Server端的核心,还包括几个定时任务
  7. NettyServer启动

代码如下,删除了非核心代码

public static void main(String[] args) throws IOException {// 获取port的几种形式:从容器中获取;从命令行获取;默认端口, use to logback.xmlint port = PortHelper.getPort(args);System.setProperty(ConfigurationKeys.SERVER_PORT, Integer.toString(port));// 解析启动参数,分容器和非容器两种情况ParameterParser parameterParser = new ParameterParser(args);// Metric相关MetricsManager.get().init();// NettyServer初始化NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads);// 核心控制器初始化DefaultCoordinator coordinator = new DefaultCoordinator(nettyRemotingServer);coordinator.init();// NettyServer启动nettyRemotingServer.init();
}

为社么说步骤3中肯能涉及到配置管理的初始化呢?核心代码如下:

if (StringUtils.isBlank(storeMode)) {storeMode = ConfigurationFactory.getInstance().getConfig(ConfigurationKeys.STORE_MODE,SERVER_DEFAULT_STORE_MODE);
}

如果在启动参数中没有特别指定storeMode,就会通过ConfigurationFactory相关API去获取该配置,在ConfigurationFactory.getInstance()这行代码中,涉及到两部分内容:ConfigurationFactory静态代码初始化和Configuration初始化。接下来我们重点分析这部分内容

配置管理初始化

ConfigurationFactory初始化

我们知道在Seata中有两个关键配置文件:一个是registry.conf,这是核心配置文件,必须要有;另一个是file.conf,只有在配置中心是File的情况下才需要用到。ConfigurationFactory静态代码块中,其实主要就是加载registry.conf文件,大概如下:

1、在没有手动配置的情况,默认读取registry.conf文件,封装成一个FileConfiguration对象,核心代码如下:

Configuration configuration = new FileConfiguration(seataConfigName,false);
FileConfigFactory.load("registry.conf", "registry");
FileConfig fileConfig = EnhancedServiceLoader.load(FileConfig.class, "CONF", argsType, args);

2、配置增强:类似代理模式,获取配置时,在代理对象里面做一些其他处理,下面详细介绍

Configuration extConfiguration = EnhancedServiceLoader.load(ExtConfigurationProvider.class).provide(configuration);

3、将步骤2中的代理对象赋值给CURRENT_FILE_INSTANCE引用,在很多地方都直接用到了CURRENT_FILE_INSTANCE这个静态引用

CURRENT_FILE_INSTANCE = extConfiguration == null ? configuration : extConfiguration;

可以简单的认为:CURRENT_FILE_INSTANCE对应的就是registry.conf里面的内容。我认为registry.conf这个文件名取的不太好,歧义太大,叫做bootstrap.conf是不是更好一些?

Configuration初始化

Configuration其实就是对应配置中心,Seata目前支持的配置中心很多,几乎主流的配置中心都支持,如:apollo、consul、etcd、nacos、zk、springCloud、本地文件。当使用本地文件作为配置中心的时候,涉及到file.conf的加载,当然这是默认的名字,可以自己配置。到这里,大家也基本上知道了registry.conffile.conf的关系了。

Configuration作为单例放在ConfigurationFactory中,所以Configuration的初始化逻辑也是在ConfigurationFactory中,大概流程如下:
1、先从registry.conf文件中读取config.type属性,默认就是file

configTypeName = CURRENT_FILE_INSTANCE.getConfig(ConfigurationKeys.FILE_ROOT_CONFIG + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR+ ConfigurationKeys.FILE_ROOT_TYPE);

2、基于config.type属性值加载配置中心,比如默认是:file,则先从registry.conf文件中读取config.file.name读取本地文件配置中心对应的文件名,然后基于该文件名创建FileConfiguration对象,这样就将file.conf中的配置加载到内存中了。同理,如果配置的是其他配置中心,则会通过SPI初始化其他配置中心。还有一点需要注意的是,在这阶段,如果配置中心是本地文件,则会为其创建代理对象;如果不是本地文件,则通过SPI加载对应的配置中心

if (ConfigType.File == configType) {String pathDataId = String.join("config.file.name");String name = CURRENT_FILE_INSTANCE.getConfig(pathDataId);configuration = new FileConfiguration(name);try {// 配置增强 代理extConfiguration = EnhancedServiceLoader.load(ExtConfigurationProvider.class).provide(configuration);} catch (Exception e) {LOGGER.error("failed to load extConfiguration:{}", e.getMessage(), e);}
} else {configuration = EnhancedServiceLoader.load(ConfigurationProvider.class, Objects.requireNonNull(configType).name()).provide();
}

3、基于步骤2创建的Configuration对象,为其再创建一层代理,这个代理对象有两个作用:一个是本地缓存,不需要每次获取配置的时候都从配置中获取;另一个是监听,当配置发生变更会更新它维护的缓存。如下:

if (null != extConfiguration) {configurationCache = ConfigurationCache.getInstance().proxy(extConfiguration);
} else {configurationCache = ConfigurationCache.getInstance().proxy(configuration);
}

到这里,配置管理的初始化就完成了。Seata通过先先加载registry.conf文件获取对应的配置中心信息、注册中心,然后再根据获取到的的对应信息初始化配置中心。在使用本地文件作为配置中心的情况下,默认是加载file.conf文件。然后再为对应的配置中心创建对应的代理对象,使其支持本地缓存和配置监听

整理流程还是比较简单,在这里我要抛出几个问题:

  1. 什么是配置增强?Seata中的配置增强是怎么做的?
  2. 如果使用本地文件作为配置中心,就必须要将配置定义在file.conf文件中。如果是Spring应用,能不能直接将对应的配置项定义在application.yaml中?
  3. 在上面说的步骤2中,为什么在使用本地文件配置中心的情况下,要先为Configuration创建对应配置增强代理对象,而其他配置中心不用?

这3个问题都是紧密联系的,都和Seata的配置增加相关。下面详细介绍

配置管理增强

配置增强,简单来说就是为其创建一个代理对象,在执行目标独对象的目标方法时候,执行代理逻辑,从配置中心的角度来讲,就是在通过配置中心获取对应配置的时候,执行代理逻辑。

  1. 通过ConfigurationFactory.CURRENT_FILE_INSTANCE.getgetConfig(key)获取配置
  2. 加载registry.conf文件创建FileConfiguration对象configuration
  3. 基于SpringBootConfigurationProviderconfiguration创建代理对象configurationProxy
  4. configurationProxy中获取配置中心的连接信息file zk nacos 等
  5. 基于连接信息创建配中心Configuration对象configuration2
  6. 基于SpringBootConfigurationProviderconfiguration2创建代理对象configurationProxy2
  7. 执行configurationProxy2的代理逻辑
  8. 基于key找到对应的SpringBean
  9. 执行SpringBean的getXxx方法

配置增强实现

上面也简单提到过配置增强,相关代码如下:

EnhancedServiceLoader.load(ExtConfigurationProvider.class).provide(configuration);
  1. 首先通过SPI机获取一个ExtConfigurationProvider对象,在Seata中默认只有一个实现:SpringBootConfigurationProvider
  2. 通过ExtConfigurationProvider#provider方法为Configuration创建代理对象

核心代码如下:

public Configuration provide(Configuration originalConfiguration) {return (Configuration) Enhancer.create(originalConfiguration.getClass(), new MethodInterceptor() {@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)throws Throwable {if (method.getName().startsWith("get") && args.length > 0) {Object result = null;String rawDataId = (String) args[0];if (args.length == 1) {result = get(convertDataId(rawDataId));} else if (args.length == 2) {result = get(convertDataId(rawDataId), args[1]);} else if (args.length == 3) {result = get(convertDataId(rawDataId), args[1], (Long) args[2]);}if (result != null) {//If the return type is String,need to convert the object to stringif (method.getReturnType().equals(String.class)) {return String.valueOf(result);}return result;}}return method.invoke(originalConfiguration, args);}});
}private Object get(String dataId) throws IllegalAccessException, InstantiationException {String propertyPrefix = getPropertyPrefix(dataId);String propertySuffix = getPropertySuffix(dataId);ApplicationContext applicationContext = (ApplicationContext) ObjectHolder.INSTANCE.getObject(OBJECT_KEY_SPRING_APPLICATION_CONTEXT);Class<?> propertyClass = PROPERTY_BEAN_MAP.get(propertyPrefix);Object valueObject = null;if (propertyClass != null) {try {Object propertyBean = applicationContext.getBean(propertyClass);valueObject = getFieldValue(propertyBean, propertySuffix, dataId);} catch (NoSuchBeanDefinitionException ignore) {}} else {throw new ShouldNeverHappenException("PropertyClass for prefix: [" + propertyPrefix + "] should not be null.");}if (valueObject == null) {valueObject = getFieldValue(propertyClass.newInstance(), propertySuffix, dataId);}return valueObject;
}

1、如果方法是以get开头,并且参数个数为1/2/3,则执行其他的获取配置的逻辑,否则执行原生Configuration对象的逻辑
2、我们没必要纠结为啥是这样的规则,这就是Seata的一个约定
3、其他获取配置的逻辑,就是指通过Spring的方式获取对应配置值

到这里已经清楚了配置增强的原理,同时,也可以猜测得出唯一的ExtConfigurationProvider实现SpringBootConfigurationProvider,肯定是和Spring相关

配置增强与Spring

在介绍这块内容之前,我们先简单介绍一下Seata的使用方式:

  1. 非Starter方式:引入依赖 seata-all, 然后手动配置几个核心的Bean
  2. Starter方式: 引入依赖seata-spring-boot-starter,全自动准配,不需要自动注入核心Bean

SpringBootConfigurationProvider就在seata-spring-boot-starter模块中,也就是说,当我们通过引入seata-all的方式来使用Seata时,配置增强其实没有什么作用,因为此时根本找不到ExtConfigurationProvider实现类,自然就不会增强。

seata-spring-boot-starter是如何将这些东西串联起来的?

1、首先,在seata-spring-boot-starter模块的resources/META-INF/services目录下,存在一个spring.factories文件,内容分如下

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.seata.spring.boot.autoconfigure.SeataAutoConfiguration,\# 暂时不管
io.seata.spring.boot.autoconfigure.HttpAutoConfiguration

2、在SeataAutoConfiguration文件中,会创建以下Bean: GlobalTransactionScanner 、SeataDataSourceBeanPostProcessor、SeataAutoDataSourceProxyCreator、SpringApplicationContextProvider。前3个和我们本文要讲的内容不相关,主要关注SpringApplicationContextProvider,核心代码非常简单,就是将ApplicationContext保存下来:

public class SpringApplicationContextProvider implements ApplicationContextAware {@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {ObjectHolder.INSTANCE.setObject(OBJECT_KEY_SPRING_APPLICATION_CONTEXT, applicationContext);}
}

3、然后,在SeataAutoConfiguration文件中,还会将一些xxxProperties.Class和对应的Key前缀缓存到PROPERTY_BEAN_MAP中。``xxxProperties就简单理解成application.yaml`中的各种配置项:

static {PROPERTY_BEAN_MAP.put(SEATA_PREFIX, SeataProperties.class);PROPERTY_BEAN_MAP.put(CLIENT_RM_PREFIX, RmProperties.class);PROPERTY_BEAN_MAP.put(SHUTDOWN_PREFIX, ShutdownProperties.class);...省略...
}

至此,整个流程其实已经很清晰,在有SpringBootConfigurationProvider配置增强的时候,我们获取一个配置项的流程如下:

  1. 先根据p配置项Key获取对应的xxxProperties对象
  2. 通过ObjectHolder中的ApplicationContext获取对应xxxProperties的SpringBean
  3. 基于xxxProperties的SpringBean获取对应配置的值
  4. 至此,通过配置增强,我们成功的获取到application.yaml中的值
http://www.hrbkazy.com/news/16077.html

相关文章:

  • 模板建站和定制建站个人如何优化网站有哪些方法
  • 500网站建设英文seo兼职
  • 西安免费网站建设百度收录提交入口地址
  • 烟台免费做网站什么样的人适合做营销
  • 深圳哪家制作网站好seo视频教学网站
  • 南宁网站开发推广app大全
  • 专门做网站的软件网店推广方法有哪些
  • 怎么做百度网盘链接网站山西seo排名厂家
  • 长春建网站公司北京seo优化外包
  • 用那种语言做网站比较好百度快照没有了用什么代替了
  • 网站建设的对比分析杭州网站推广大全
  • 如果网站曾被挂木马自媒体平台排名前十
  • 能打开各种网站的浏览器appit培训
  • 中国联通网站备案系统如何推广品牌
  • 镇江百度送网站简单的网页设计作品
  • 郑州制作网站价格百度搜索平台
  • 做网站主播要什么条件推广手段和渠道有哪些
  • 推广广告赚佣金seo推广话术
  • 朝阳市做网站的公司网络营销seo是什么意思
  • 南昌网站建设志博友链价格
  • 邮件网站排名抖音推广方式有哪些
  • ps联盟网站怎么搞自己的网站
  • 网站通常用什么编程做合肥网站建设公司
  • 如何做b2b网站最近新闻热点国家大事
  • 做服装网站要那些照片廊坊seo网络推广
  • 整站建设和网站优化seo推广的方法
  • wordpress 企业插件北京seo排名外包
  • 几何印花图案设计网站什么是网络营销?
  • 南昌制作网站软件教育培训网站模板
  • 重庆永川网站建设价格广东云浮疫情最新情况