使用sentinel 遇到的一些坑

sentinel使用起来,并不是那么的容易。特别是用在gateway网关中,更是到处都是坑。

  1. gateway整合sentinel ,也就是在网关层面,实现使用sentinel限流。限流包括针对客户端ip限流,针对热点参数限流,针对head的某个字段限流。

  2. 在经过修改源码以后,能够实现将sentinel的限流规则从dashbord推送到nacos。

使用sentinel因为版本没选对,而导致sentinel限流不生效问题
各种不生效问题,多半是因为选用版本造成的。sentinel的官方文档上,并没有告诉我们,我们具体应该使用哪个版本。这就导致了,网上、社区里,官方群里,到处都是问为什么我的sentinel不生效。

在gateway 中刚引入sentinel的时候,限流不生效。官方文档没有告诉我们,springboot的版本大于 2.2.0 小于 2.3.1的。这个官方文档上并没有说。如果超出这个范围就是不生效。

sentinel官方版本,是不支持 持久化限流规则的。在官方文档上,告诉我们,这样不能上生产,想要上生产,必须改造源码。至于怎么改造,没有明说,官网的例子很难看懂。不过毕竟是有收费版的,如果这个大家都能用了,谁还去用收费版呢!

能够上生产的sentinel,必须是把限流规则持久化到例如 nacos,等文件中。我们希望在生产中,能够不重启网关服务,就能够进行修改流控规则。我们最想要在sentinel提供的dashbord控制台修改了限流规则,然后把这个规则推到nacos,然后由我们的网关客户端吗,把它加载到内存中,并且限流生效。我选用的是使用nacos来做持久化,源码也是针对nacos来改造的。其实也不是很难,抓住一个关键点,无非就是找到把限流规则加载到内存中的操作,替换成推送到nacos。始终都是围绕这个点来展开的

而限流规则一共有这么几种方式:

通过编写代码的方式(弊端就是,每次修改规则,都需要重启网关,但凡是线上项目,都不会每次都重启项目来更新限流规则);
通过sentinel提供的dashbord控制台(官方实现的是基于内存的,重启项目,就会丢失,相当于是每次重启项目,都需要手动重新配制限流规则);
或者引入第三方放数据源(支持nacos,文件,等。但是想要使用这个,都是需要自己实现的,需要改源码的。本身sentinel源码里边并不支持,只能通过改源码)。

使用sentinel因为版本没选对,而导致sentinel限流不生效问题

sentinel如何选择和springboot适配的版本,如何选择和springCloud适配的版本,如何选择和 springCloudAlibaba适配的版本。在官网上没有,但是在 springCloudAlibaba里边提到了sentinel,这是官网地址:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

用户权限的问题

feign是spring cloud提供的一个声明式伪http客户端,让调用远程服务就像调用本地服务一样。为了进行服务容错,所以开启了feign关于sentinel的支持,在本地开发环境,有A、B两个服务,分别已启动,A通过feign调用B服务的某个方法,可以正常返回结果。然后将B服务停掉,也可以正常进入A服务提供的容错处理类对应的方法。然后通过jenkins打完A服务的可运行jar包,部署到测试环境,此时B服务并没有部署到测试环境,按理说此时A去调用B服务,应该给出服务容错的相关提示信息,但是却给出:org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.alibaba.csp.sentinel.context.ContextUtil。

分析
看到NoClassDefFoundError,排查步骤:
① ContextUtil是否有在项目里或者依赖的jar包里
② 是否jar包依赖冲突导致
经过上面两个步骤的排查,返现jar包依赖正常,ContextUtil就在sentinel-core里;后来发现使用jenkins打包,然后到目标服务器启动A服务对应的jar包,使用的普通用户:比如appuser。后面手动使用root用户启动A服务的jar包,发现正常进入服务容错了。这时候毕本可以定位应该是因为用户权限的问题导致。后面还是用普通用户通过远程debug jar包才找到问题,看到输出了一条关键的日志,但是不用debug却没有这条日志:Permission denied /home/appuser/logs/csp/sentinel-record.log.2021-03-18.0.lck。
然后到/home/appuser目录下,发现有logs目录(很早以前就创建),但归属所属用户和组都是root,修改该目录所属用户和组为appuser。修改完成,使用appuser用户重新启动A服务,正常进入服务容错,不再出现:Could not initialize class com.alibaba.csp.sentinel.context.ContextUtil。

小结
将服务部署到linux服务器,需要注意当前用户是否对目录具有可读可写可执行的权限,以免出现像上述这样的错误,因为使用sentinel,会往用户自己的home目录写数据

远程debug方法:
1)目标服务器启动服务:java -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n -jar xxx.jar --spring.profiles.active=test
2)本地IDEA使用remote启动,打断点
3)访问服务器上的API,即可远程debug

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值