Sentinel 1.8.4 规则持久化源码分析
2025-02-26 15:10:07   0  举报             
     
         
 Sentinel规则持久化源码分析,分享给大家学习。 更多干货内容,欢迎关注我的公众号:Fox爱分享
    作者其他创作
 大纲/内容
 FlowControllerV1#apiQueryMachineRules
    解析请求,获取/user/findOrderByUserId/{id}作为资源名
  Sentinel-Dashboard
  PropertyListener
  先初始化AbstractDataSource,赋值converter-------> 对应规则的解析器SentinelProperty----->DynamicSentinelProperty对象
  2.推送规则
  用户修改流控规则
  CommandCenter
  微服务接入Sentinel Dashboard控制台启动
  根据dataSourceName注册beanClass为NacosDataSourceFactoryBean的BeanDefinition
  从Nacos配置中心读取dataId的配置
  解析配置
  implements
  保存流控规则
  从Nacos配置中心拉取配置
  RuleFileUtils.mkdirIfNotExits(PersistenceRuleConstant.storePath);     RuleFileUtils.createFileIfNotExits(PersistenceRuleConstant.rulesMap);
  ParamFlowRuleManager.register2Property(dataSource.getProperty())
  FileWritableDataSource#write
  获取所有的machineRules流控规则
  更新内存
  this.lastModified = file.lastModified();        firstLoad();
  创建流控规则的读数据源FileRefreshableDataSource,需要流控规则的文件路径
  CommandHandlerProvider.getInstance().namedHandlers()
  RuleManager
  SimpleHttpCommandCenter.ServerThread#run
  Sentinel Dashboard
  RequestOriginParser
  判断ruleType
  创建ServerSocket并绑定端口,端口会从8719开始,如果占用+1
  InitFunc
  通过SPI机制获取到所有的CommandHandler实例,并保存到map中。通过@CommandMapping注解指定key名称,CommandHandler作为value
  改造Sentinel Deashboard,将规则发布到配置中心
  1.用户通过控制台添加规则
  currentProperty.removeListener(LISTENER);            property.addListener(LISTENER);            currentProperty = property;
  从flowRules中获取流控规则,然后响应给sentinel dashboard
  注意: 不同的规则配置解析需要对应的解析器,否则可能导致配置规则不生效
  getContextName(request)
  repository.saveAll(rules)
  sentineldataSource
  规则缓存
  写入数据源
  调用接口/v1/flow/rule,请求参数被封装为FlowRuleEntity
  持久化到本地文件
  commandCenter.beforeStart()
  循环执行initList的init方法
  FlowRuleNacosProvider#getRules
  serverInitTask的run方法
  返回资源上下文的名称
  DispatcherServlet#doDispatch
  FactoryBean
  baseWebMvcConfig.getOriginParser().parseOrigin(request)
  BlockExceptionHandler
  SentinelWebMvcConfig
  NacosDataSourceFactoryBean#getObject
  Listener#receiveConfigInfo
  获取到Nacos配置中心服务
  executor.submit(new ServerThread(serverSocket))
  FlowRuleManager.register2Property(dataSource.getProperty())
  parser.convert(conf)
  改造Sentinel Deashboard,从到配置中心拉取规则
  Converter 
  flowDataSource = datasource
  通过request获取来源标识
  1.用户通过Nacos配置中心控制台添加规则
   chain.entry
  注册datasource的property到 RuleManager
  commandHandler = SimpleHttpCommandCenter.getHandler(commandName)
  ReadableDataSource
  从本地读取流控规则文件flowRule.json
  response = ModifyRulesCommandHandler#handler
  注册所有的CommandHandler到CommandCenter的handlerMap中
  调用springmvc拦截器
  创建写流控规则的数据源FileWritableDataSource
  获取文件最后的修改时间,并且加载文件
  用新规则替换旧规则,并通知所有属性监听器回调configUpdate方法(前提:当新值不等于旧值时)
  CommandResponse.ofSuccess(JSON.toJSONString(FlowRuleManager.getRules()))
  可读数据源注册至FlowRuleManager 这样当规则文件发生变化时,就会更新规则到内存
  repository.save(entity)
  写数据源接口
  listener.configUpdate(newValue)
  加载流控规则
  4.更新rules
  通过SPI机制获取到SimpleHttpCommandCenter对象
  异步设置流控规则
  SentinelWebInterceptor#getResourceName
  可读数据源接口
  this.configListener = new Listener(){}
  configService.getConfig
  webContextUnify用于控制是否收敛context,将其配置为false即可根据不同的URL进行链路限流。webContextUnify默认为true,统一入口为sentinel_web_servlet_context,导致链路限流不生效。
  根据命令找到对应的处理器
  SentinelWebAutoConfiguration
  根据type类型处理不同的规则
  查看流控规则列表
  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事件执行线程
  更新配置到内存中
  ContextUtil.getContext()
  微服务启动
  机器3
  流控规则的属性监听器
  给DynamicSentinelProperty绑定FlowPropertyListener
  解析配置,并更新到内存
  当dataId的数据发生变化后,就会回调listener
  type=flow处理流控规则
  flowRules = rules
  SentinelDataSourceHandler#afterSingletonsInstantiated
  new Thread(serverInitTask).start()
  更新规则配置到内存中
  规则存储接口
  将流控规则的写数据源注册到WritableDataSourceRegistry的flowDataSource,getFlowDataSource()不为空
  如果是新增规则,Sentinel Client处理setRules
  CommandCenterProvider.getCommandCenter()
  FlowPropertyListener#configUpdate
  解析资源的请求来源origin
  循环解析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.8.8.RELEASE.jar
  Spring容器初始化所有的非懒加载单例bean之后调用
  SmartInitializingSingleton
  清掉内存中旧的流控规则,保存新的流控规则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.8.RELEASE.jar!\\META-INF\\spring.factories
  机器2
  Sentinel Dashboard推送规则,发起post请求http://192.168.3.1:8721/setRules
  3.配置中心配置文件发生变更,监听器就会执行回调方法,更新配置规则到内存
  以热点参数规则为例dataSourceName:  param-flow-rules-sentinel-nacos-datasourcebeanClass: com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean
  被修改过
  getServerSocketFromBasePort(port)
  springmvc的核心入口
  根据DataSourceName,利用FactoryBean获取到对应规则的NacosDataSource对象
  AutoRefreshDataSource 
  loadInitialConfig()
  第一次会调用,Env初始化阶段执行静态代码块
  1.用户通过Sentinel控制台添加规则
  用户新增流控规则
  3.更新到内存中
  通信模块
  获取所有的流控规则
  CtSph#entryWithPriority
  授权规则的扩展点:来源访问控制,根据资源的请求来源(`origin`)限制资源是否通过
  创建资源上下文
  this.configService = NacosFactory.createConfigService(this.properties)
  解析数据为流控规则数组
  w.func.init()
  以流控规则为例
  AbstractSentinelInterceptor
  InMemoryRuleRepositoryAdapter#save
  初始化CommandCenter
  SentinelProperty
  BlockException异常处理
  第6步如何实现?这种方式属于pull模式,FileRefreshableDataSource 会周期性(3s)的读取文件以获取规则,当文件有更新时会及时发现,并将规则更新到内存中。
  根据ruleType注册到不同的规则管理器
  SentinelWebInterceptor
  本地规则存储文件
  DynamicSentinelProperty.updateValue(rules)
  springmvc拦截器接口
  HandlerInterceptor
  先初始化AbstractDataSource,赋值converter和SentinelProperty----->DynamicSentinelProperty对象
  发布规则
  保存所有的流控规则
  CommandCenterInitFunc#init
  SentinelApiClient#executeCommand
  机器1
  save(rule)
  可读数据源注册至FlowRuleManager 这样当规则发生变化时,就会更新规则到内存
  返回流控规则列表
  configService#publishConfig
  通过SPI机制加载sentinel相关依赖包下META-INF/services/下所有的InitFunc实例类
  parseOrigin(request)
  用来和控制台进行交互的处理逻辑
  发布规则到Nacos配置中心
  sentinel-datasource-nacos-1.8.4.jar
  beanFactory.getBean()
  如果dataSource不为空
  dataSource.write(value)
  FlowRuleManager.loadRules(flowRules)
  获取到上下文context
  WebMvcConfigurer
  NacosDataSource实现原理
  WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS)
  WritableDataSource
  param-flow
  SentinelWebInterceptor#getContextName
  创建配置监听器
  开启服务线程
  以流控规则为例,处理流控规则
  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()
  SpiLoader.of(InitFunc.class).loadInstanceListSorted()
  Nacos Dashboard
  HttpEventTask#run
  如果是流控规则
  dataSourceProperties.postRegister(newDataSource)
  Env
  6.监控线程会周期性监控本地文件,当本地文件发生变更,就会触发监控逻辑,将变更的配置更新到内存
  Spring webmvc的逻辑
  sentinel核心逻辑,进入资源保护逻辑
  获取规则类型和数据,类型用于判断规则类型,包括:流控,授权,降级,系统规则
  flow
  Sentinel Dashboard发起Get请求http://192.168.3.1:8720/getRules?type=flow
  initNacosListener()
  AbstractSentinelInterceptor#preHandle
    
    收藏 
      
    收藏 
     
 
 
 
 
  0 条评论
 下一页
  
   
   
  
  
  
  
  
  
  
  
 