Sentinel 1.8.0规则持久化源码分析
2024-10-18 15:24:33 0 举报
Sentinel 1.8.0规则持久化源码分析
作者其他创作
大纲/内容
FlowControllerV1#apiQueryMachineRules
Sentinel-Dashboard
PropertyListener
不存在CommonFilter
先初始化AbstractDataSource,赋值converter-------> 对应规则的解析器SentinelProperty----->DynamicSentinelProperty对象
SentinelWebInterceptor
2.推送规则
用户修改流控规则
微服务接入Sentinel Dashboard控制台启动
解析请求,获取/user/findOrderByUserId/1作为资源名
根据dataSourceName注册beanClass为NacosDataSourceFactoryBean的BeanDefinition
从Nacos配置中心读取dataId的配置
解析配置
implements
保存流控规则
从Nacos配置中心拉取配置
RuleFileUtils.mkdirIfNotExits(PersistenceRuleConstant.storePath); RuleFileUtils.createFileIfNotExits(PersistenceRuleConstant.rulesMap);
ParamFlowRuleManager.register2Property(dataSource.getProperty())
FileWritableDataSource#write
获取所有的machineRules流控规则
更新内存
RequestOriginParser的实现类想要生效需要交给WebCallbackManager管理
this.lastModified = file.lastModified(); firstLoad();
创建流控规则的读数据源FileRefreshableDataSource,需要流控规则的文件路径
CommandHandlerProvider.getInstance().namedHandlers()
RuleManager
SimpleHttpCommandCenter.ServerThread#run
Sentinel Dashboard
RequestOriginParser
判断ruleType
InitFunc
创建ServerSocket并绑定端口,端口会从8719开始,如果占用+1
通过SPI机制获取到所有的CommandHandler实例,并保存到map中。通过@CommandMapping注解指定key名称,CommandHandler作为value
改造Sentinel Deashboard,将规则发布到配置中心
1.用户通过控制台添加规则
currentProperty.removeListener(LISTENER); property.addListener(LISTENER); currentProperty = property;
从flowRules中获取流控规则,然后响应给sentinel dashboard
注意: 不同的规则配置解析需要对应的解析器,否则可能导致配置规则不生效
repository.saveAll(rules)
sentineldataSource
规则缓存
写入数据源
调用接口/v1/flow/rule,请求参数被封装为FlowRuleEntity
持久化到本地文件
commandCenter.beforeStart()
循环执行initList的init方法
FlowRuleNacosProvider#getRules
serverInitTask的run方法
DispatcherServlet#doDispatch
FactoryBean
originParser.parseOrigin(request)
BlockExceptionHandler
SentinelWebMvcConfig
NacosDataSourceFactoryBean#getObject
Listener#receiveConfigInfo
获取到Nacos配置中心服务
executor.submit(new ServerThread(serverSocket))
判断是否为资源添加http method作为前缀,比如{GET:/user/findOrderByUserId/1}
FlowRuleManager.register2Property(dataSource.getProperty())
parser.convert(conf)
Converter
改造Sentinel Deashboard,从配置中心拉取规则
flowDataSource = datasource
CommonFilter#doFilter
通过request获取来源标识
1.用户通过Nacos配置中心控制台添加规则
chain.entry
注册datasource的property到 RuleManager
commandHandler = SimpleHttpCommandCenter.getHandler(commandName)
ReadableDataSource
从本地读取流控规则文件flowRule.json
response = ModifyRulesCommandHandler#handler
注册所有的CommandHandler到CommandCenter的handlerMap中
RequestOriginParser originParser = WebCallbackManager.getRequestOriginParser()
创建写流控规则的数据源FileWritableDataSource
获取文件最后的修改时间,并且加载文件
用新规则替换旧规则,并通知所有属性监听器回调configUpdate方法(前提:当新值不等于旧值时)
CommandResponse.ofSuccess(JSON.toJSONString(FlowRuleManager.getRules()))
可读数据源注册至FlowRuleManager 这样当规则文件发生变化时,就会更新规则到内存
repository.save(entity)
写数据源接口
listener.configUpdate(newValue)
加载流控规则
UrlCleaner
BlockException异常处理
4.更新rules
通过SPI机制获取到SimpleHttpCommandCenter对象
异步设置流控规则
拦截路径通过SentinelProperties.Filter获取,默认/**
可读数据源接口
this.configListener = new Listener(){}
configService.getConfig
用于控制是否收敛context,将其配置为false即可根据不同的URL进行链路限流。webContextUnify为true,统一入口为sentinel_web_servlet_context,导致链路限流不生效。
根据命令找到对应的处理器
SentinelWebAutoConfiguration
根据type类型处理不同的规则
查看流控规则列表
httpMethodSpecify默认为false
checkEntityInternal(entity)
利用InitFunc扩展实现FileDataSource初始化逻辑:当用户访问sentinel资源时,会初始化此模块,从本地文件加载sentinel规则。当文件配置发生变更时,利用读数据源监听配置规则的变化,将配置更新到内存当sentinel控制台推送规则是,利用写数据源将配置更新到规则文件
this.parser = parser; this.property = new DynamicSentinelProperty<T>();
DefaultBlockExceptionHandler#handle
while(true)死循环监听当前端口
http://localhost:8800/user/findOrderByUserId/1
FileRefreshableDataSource#readSource
此处扩展点,推送规则可以直接发布到Nacos配置中心
/v1/flow/rules
创建NacosDataSource对象
for循环保存规则到内存中
CommandHandler
实现SmartInitializingSingleton的接口后,当所有非懒加载的单例 bean 都初始化完成以后, Spring的IOC容器会回调该接口的 afterSingletonsInstantiated()方法
当配置文件发生变更会回调
FileDataSourceInit#init
5.用户修改本地规则存储文件
初始化AutoRefreshDataSource,扩展自动更新功能
T newValue = NacosDataSource.this.parser.convert(configInfo)getProperty().updateValue(newValue)
持久化的关键在于WritableDataSourceRegistry#getFlowDataSource能否获取到dataSource。可以通过WritableDataSourceRegistry#registerFlowDataSource设置dataSource
为dataId添加监听器
FlowRuleManager.register2Property(flowRuleRDS.getProperty())
socket事件执行线程
Filter
更新配置到内存中
ContextUtil.getContext()
调用addInterceptors,注册拦截器
微服务启动
机器3
流控规则的属性监听器
给DynamicSentinelProperty绑定FlowPropertyListener
解析配置,并更新到内存
当dataId的数据发生变化后,就会回调listener
target = urlCleaner.clean(target)
type=flow处理流控规则
flowRules.clear();flowRules.putAll(rules);
SentinelDataSourceHandler#afterSingletonsInstantiated
new Thread(serverInitTask).start()
更新规则配置到内存中
规则存储接口
将流控规则的写数据源注册到WritableDataSourceRegistry的flowDataSource,getFlowDataSource()不为空
如果是新增规则,Sentinel Client处理setRules
CommandCenterProvider.getCommandCenter()
FlowPropertyListener#configUpdate
解析资源的请求来源origin
Servlet的过滤器
循环解析InitFunc实现类封装成OrderWrapper对象并排序
executeCommand(new HttpGet(urlBuilder.toString()))
sentinel-datasource-extension.jar包中实现
微服务A
T newValue = loadConfig()
commandName = HttpCommandUtils.getTarget(request)
保存到内存中,存入三个map:allRules,machineRules,appRules
spring-cloud-alibaba-sentinel-datasource-2.1.1.RELEASE.jar
SmartInitializingSingleton
Spring容器初始化所有的非懒加载单例bean之后调用
清掉内存中旧的流控规则,保存新的流控规则flowRules
4.将规则更新到本地文件,需要实现WritableDataSource
将可写数据源注册至 transport 模块的 WritableDataSourceRegistry 中,这样收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中.
开启线程监控本地文件最后的修改时间,周期3s,线程前缀sentinel-datasource-auto-refresh-task
allRules.clear(); machineRules.clear(); appRules.clear();
清掉内存中的规则数据
1.创建了一个cpu线程数大小的固定线程池,用来做业务线程池。2.开启服务线程创建ServerSocket绑定端口,默认8719,实时监听sentinel-dashboard发送的请求
isModified()
解析Sentinel Dashboard发送过来的请求,获取请求的命令
FlowRuleNacosPublisher#publish
用户发起调用请求
commandCenter.start()
RuleRepository
lookProcessChain(resourceWrapper)
FlowControllerV1#apiAddFlowRule
DynamicRulePublisher
getProperty().updateValue(newValue)
Sentinel Client监听端口
extends
spring-cloud-starter-alibaba-sentinel-2.2.5.RELEASE.jar!\\META-INF\\spring.factories
机器2
Sentinel Dashboard推送规则,发起post请求http://192.168.3.1:8721/setRules
webContextUnify默认是true
3.配置中心配置文件发生变更,监听器就会执行回调方法,更新配置规则到内存
以热点参数规则为例dataSourceName: param-flow-rules-rules-sentinel-nacos-datasourcebeanClass: com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean
被修改过
getServerSocketFromBasePort(port)
Spring webmvc的逻辑
根据DataSourceName,利用FactoryBean获取到对应规则的NacosDataSource对象
AutoRefreshDataSource
loadInitialConfig()
第一次会调用,Env初始化阶段执行静态代码块
正常逻辑
1.用户通过Sentinel控制台添加规则
用户新增流控规则
3.更新到内存中
通信模块
获取所有的流控规则
CtSph#entryWithPriority
授权规则的扩展点:来源访问控制根据资源的请求来源(`origin`)限制资源是否通过
创建资源上下文
this.configService = NacosFactory.createConfigService(this.properties)
解析数据为流控规则数组
w.func.init()
以流控规则为例
InMemoryRuleRepositoryAdapter#save
初始化CommandCenter
SentinelProperty
异常逻辑:BlockException的处理
第6步如何实现?这种方式属于pull模式,FileRefreshableDataSource 会周期性(3s)的读取文件以获取规则,当文件有更新时会及时发现,并将规则更新到内存中。
根据ruleType注册到不同的规则管理器
本地规则存储文件
DynamicSentinelProperty.updateValue(rules)
HandlerInterceptor
先初始化AbstractDataSource,赋值converter和SentinelProperty----->DynamicSentinelProperty对象
发布规则
CommandCenterInitFunc#init
保存所有的流控规则
SentinelApiClient#executeCommand
机器1
save(rule)
可读数据源注册至FlowRuleManager 这样当规则发生变化时,就会更新规则到内存
返回流控规则列表
configService#publishConfig
通过SPI机制加载sentinel相关依赖包下META-INF/services/下所有的InitFunc实例类
parseOrigin(sRequest)
用来和控制台进行交互的处理逻辑
发布规则到Nacos配置中心
sentinel-datasource-nacos-1.8.0.jar
beanFactory.getBean()
如果dataSource不为空
dataSource.write(value)
FlowRuleManager.loadRules(flowRules)
获取到上下文context
WebMvcConfigurer
NacosDataSource实现原理
WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS)
WritableDataSource
param-flow
创建配置监听器
UrlBlockHandler
开启服务线程
以流控规则为例,处理流控规则
registerCommands(handlers)
AbstractDataSource
sentinel系统初始化的处理逻辑
InitExecutor.doInit()
loadConfig(readSource())
创建规则存储文件
自定义BlockException异常处理
@Bean
startTimerService()
获取所有规则,Sentinel Client处理getRules命令
FetchActiveRuleCommandHandler#handle
初始化nacos监听器
加载配置
获取到ProcessorSlot chain
AbstractDataSource newDataSource = (AbstractDataSource) this.beanFactory .getBean(dataSourceName)
String type = request.getParam(\"type\"); String data = request.getParam(\"data\")
dealFlowRules()
ServiceLoaderUtil.getServiceLoader(InitFunc.class)
Nacos Dashboard
HttpEventTask#run
如果是流控规则
注意:需要sentinel-web-servlet.jar提供,微服务没有引入此依赖,不会经过CommonFilter
dataSourceProperties.postRegister(newDataSource)
Env
6.监控线程会周期性监控本地文件,当本地文件发生变更,就会触发监控逻辑,将变更的配置更新到内存
sentinel核心逻辑,定义当前要保护的资源
获取规则类型和数据,类型用于判断规则类型,包括:流控,授权,降级,系统规则
flow
Sentinel Dashboard发起Get请求http://192.168.3.1:8720/getRules?type=flow
initNacosListener()
AbstractSentinelInterceptor#preHandle
0 条评论
下一页