首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一文就把深度解析微服务高并发:动态配置的实现原理搞懂了

动态配置的实现原理

sentinel-datasource-extension模块是我们主要研究的模块,这是Sentinel实现动态数据源的核心,定义了动态数据源的接口并提供了抽象类。

SentinelProperty

SentinelProperty是Sentinel提供的一个接口,可被注册到Sentinel提供的各种规则的Manager(FlowRuleManager)中。SentinelProperty可以给SentinelProperty添加监听器,在配置改变时,用户可以调用SentinelProperty#updateValue方法,由该方法负责调用监听器去更新规则,而不需要调用FlowRuleManager#loadRules方法。同时,用户可以注册额外的监听器,在配置改变时做一些其他的事情。

SentinelProperty并不是在sentinel-datasource-extension模块中定义的接口,而是在sentinel-core模块中定义的接口,其源码如下:

addListener:添加监听器。

removeListener:移除监听器。

updateValue:通知所有监听器配置已更新,newValue参数为新的配置。

SentinelProperty默认使用的实现类是DynamicSentinelProperty,其实现源码如下:

从上述源码中可以看出,DynamicSentinelProperty使用Set存储已注册的监听器;

updateValue方法负责通知所有监听器,调用监听器的configUpdate方法。

在前面分析FlowRuleManager时,我们只关注了其loadRulesAPI,除了可以使用loadRules API加载规则配置,FlowRuleManager还提供了registerProperty API,用于注册一个SentinelProperty实例,以实现动态加载或更新规则配置。

使用SentinelProperty实现加载或更新限流规则配置的步骤如下:

给FlowRuleManager注册一个SentinelProperty实例,替换FlowRuleManager默认创建的SentinelProperty实例(因为外部拿不到默认的SentinelProperty)。

这一步由FlowRuleManager完成,FlowRuleManager会给SentinelProperty实例注册FlowPropertyListener监听器,该监听器负责更新FlowRuleManager.flowRules缓存的限流规则配置。

在应用启动或者规则配置改变时,只需要调用SentinelProperty#updateValue方法,由updateValue通知FlowPropertyListener监听器去更新限流规则配置。

FlowRuleManager支持使用SentinelProperty加载或更新限流规则配置的实现源码如下:

LISTENER:PropertyListener接口的实现类实例,用于监听规则配置更新,在规则配置更新时更新flowRules字段缓存的限流规则配置。

currentProperty:当前使用的SentinelProperty实例,默认会创建一个DynamicSentinelProperty实例。

register2Property:用于注册SentinelProperty实例。

实现更新缓存的限流规则配置的FlowPropertyListener是FlowRuleManager的一个内部类,其源码如下:

PropertyListener接口定义了如下两个方法:

configUpdate:在更新规则配置时被调用,被调用的时机是SentinelProperty的updateValue方法被调用时。

configLoad:在首次加载规则配置时被调用,是否被调用由SentinelProperty的实现类决定。DynamicSentinelProperty没有调用这个方法。

所以,现在有如下两种方法可用于更新限流规则配置:

调用FlowRuleManager#loadRules方法。

给FlowRuleManager注册一个SentinelProperty实例,并调用SentinelProperty实例的updateValue方法。

ReadableDataSource

Sentinel将读和写数据源抽离成两个接口(早期版本只有读接口,写接口是之后的版本才添加的功能),目前来看,写接口只在热点参数限流模块中被使用。事实上,使用读接口就可以满足我们的需求。ReadableDataSource接口的定义如下:

ReadableDataSource是一个泛型接口,参数化类型S代表用于装载从数据源中读取的配置的类型,参数化类型T代表对应Sentinel中的规则类型。例如,我们可以定义一个FlowRuleProps类,用于装载从yml配置文件中读取的限流规则配置,然后将FlowRuleProps实例转换为FlowRule实例,所以S可以被替换为FlowRuleProps,T可以被替换为List。

ReadableDataSource接口定义的方法说明如下:

loadConfig:加载配置。

readSource:从数据源中读取配置,数据源既可以是yaml配置文件,也可以是MySQL、Redis等,由实现类决定从哪种数据源中读取配置。

getProperty:获取SentinelProperty实例。

close:用于关闭数据源,例如,在使用文件存储配置时,可以在此方法中实现关闭文件输入流功能。

如果动态数据源提供SentinelProperty,则可以调用getProperty方法获取动态数据源提供的SentinelProperty实例,并将此SentinelProperty实例注册给规则管理器,这样动态数据源在读取到配置时就可以调用自身SentinelProperty实例的updateValue方法通知规则管理器更新规则。

AbstractDataSource是一个抽象类,该类可实现ReadableDataSource接口,用于简化具体动态数据源的实现,其子类只需要继承AbstractDataSource抽象类并实现readSource方法即可。

AbstractDataSource抽象类的源码如下:

AbstractDataSource抽象类要求所有子类都必须提供一个数据转换器(Converter)。

Converter用于将S类型的实例转换为T类型的实例,如将用于装载yaml配置的FlowRuleProps实例转换为FlowRule集合。

AbstractDataSource实例会在构造方法中创建DynamicSentinelProperty实例,因此子类无须创建SentinelProperty实例。

AbstractDataSource实例实现loadConfig方法,首先调用子类实现的readSource方法从数据源中读取配置,返回的实例类型为S,然后调用Converter实例的convert方法,将S类型的实例转换为T类型的实例。

Converter接口的定义如下:

convert:将类型为S的参数source转换为类型为T的实例。

本文给大家讲解的内容是深度解析微服务高并发动态数据源 :动态配置的实现原理

下篇文章给大家讲解的内容是深度解析微服务高并发动态数据源 :基于Spring Cloud动态配置实现动态数据源

感谢大家的支持!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230323A00LMH00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券