alibaba / Sentinel

A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
https://sentinelguard.io/
Apache License 2.0
22.31k stars 8k forks source link

建议给Flow/DegradationRuleManager的规则添加append方法 #3398

Open ChinaFLTV opened 4 months ago

ChinaFLTV commented 4 months ago

2024-5-19 19:11 47.碰见了非常狗血的问题,本来我web微服务模块的sentinel可以轻松集成nacos实现资源规则持久化的,结果,我在给其他微服务模块同样上了sentinel+nacos持久化后,发现web微服务模块这边拉不到nacos推送过来的规则了。 打了日志发现推送的规则可以正常接收到,然后debug进初始化代码部分,发现规则也能正常被加载进来,可偏偏sentinel控制台这边就是不显示,使用jmeter进行压测发现,规则也的的确确没有生效。起初我以为一直是我的web微服务模块这边配置的哪个环节出了问题,查了一晚上也没有什么突破性进展。 等到我十二点回宿舍,在路上,我突然意识到,会不会是web模块依赖的其他微服务模块干扰到了吧,因为其他微服务模块我也配置了,而且是在配置之后出的这个问题,而且,我还想到debug的时候发现它内部规则的初始化是直接赋值的形式而不是追加的形式,我开始怀疑应该是其他微服务模块的空规则在后来的初始化中覆盖掉了前面web模块初始化添加的规则。 话不多说,开始debug! 可以看到,请求发送来,果然首先来到了web微服务模块初始化这里(sentinel采用的懒加载形式,即请求打过来的时候才去加载资源规则): image.png 可以看到,此时nacos那边配置的9条流控规则均被成功加载进FlowRuleManager中: image.png 我们放行web模块的初始化,果不其然,来到了web微服务模块依赖的另一个微服务模块的规则初始化这里: image.png 呵呵,果然,我们的web流控规则被覆盖掉了,这里为null是因为,我没有在nacos那边配置流控规则的文件: image.png 我们深入分析一下,在这个微服务模块中的具体的初始化流程: 在经过我们配置的自定义解析器之后,然后加载配置,由于云端没有数据,所以这里为null:image.png 然后返回到加载初始化规则这里,在这里需要更新规则: image.png 但真正的规则更新以及监听器的触发是在updateValue这里,由于我们没有配置额外的监听器,这里直接在第一个if这里进行返回了,进入: image.png 此时,value直接变成了null,但此时是因为本来就是null,但我们不是之前已经初始化了9条规则吗?在debug窗口中,我们可以很清晰地发现,两个模块用到的NacosDataSource不是同一个,所以自然二者没有关系了。 虽然这两个NacosDataSource不一样,当然,其内部的Property肯定也不一样了,但是!我们的FlowRuleManager是只有一个的! image.png 你会发现,我们全程都是在调用FlowRuleManager的静态API,而且,其内部的Property竟然也是静态的! 好了,我们话不多说赶紧跟进其内部: image.png 第一次由web微服务模块初始化进入该方法,然后将获取到的9条流控规则数据整合到Property中去,这没问题,我们放行: image.png 第二次由其他微服务模块进入,你会发现,此时,我们的Property中已经有了第一次整合进的9条规则数据,但是很不幸,这次我们获取的数据为空(currentProperty是指当前FlowRuleManager中的Property数据状态,而Property才是新获取到的规则数据): image.png image.png 第二次整合结束,你会发现我们之前(上一次)整合的规则数据完全被本次的空数据给替换掉了。。。 因此,我们的sentinel控制台也自然而然的没有规则数据可展示了,请求也自然而然没有规则进行参照以进行服务降级熔断限流了。。。 (第一次写debug过程,还是有点不大习惯😑)

解决措施

ilaotan commented 1 month ago

哪家公司的微服务这么开发 直接依赖对方的service ? 这叫微服务? 自己项目边界问题,让sentinel给你解决?