使用sentinel 遇到的一些坑
Posted liuec1002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用sentinel 遇到的一些坑相关的知识,希望对你有一定的参考价值。
sentinel使用起来,并不是那么的容易。特别是用在gateway网关中,更是到处都是坑。
-
gateway整合sentinel ,也就是在网关层面,实现使用sentinel限流。限流包括针对客户端ip限流,针对热点参数限流,针对head的某个字段限流。
-
在经过修改源码以后,能够实现将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
关于阿里巴巴开源Sentinel的使用
最近在自己的项目中集成了 阿里巴巴开源的一款流量防卫组件 sentinel ,踩了一些坑,希望可以记录下,并且能够帮助到一些人。
关于官方 sentinel的一些 介绍就不多说了,如何使用官方也都给了demo,详情请看 https://github.com/spring-cloud-incubator/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/readme-zh.md
我就记录下我遇到的问题,我这个项目是 用springcloud的,所以就只写关于这个的集成。
官网文档里 写需要引入
但是我没找到这个包,所以就用源码打了包,并且加了点日志,有助于排查问题,这边上传不了jar包,就自己用源码打下包吧
这个工程的地址 是 https://github.com/spring-cloud-incubator/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-sentinel
如果项目启动的时候 配置正确的话 后台会打印出日志,如下图
如果能打印出 自己 配置的东西,说明已经配置成功,那就可以正常的使用这款强大的中间件了;
如果后台日志没有 sentinel 的内容说明你没有正确引入 这个jar 包,重新引入即可。
这款 组件切入 是 依靠 BeanPostProcessor 切入自己需要使用的逻辑功能,具体还在学习中
以上是关于使用sentinel 遇到的一些坑的主要内容,如果未能解决你的问题,请参考以下文章
吐血经验在 windows 上安装 spark 遇到的一些坑 | 避坑指南
Alibaba Sentinel对接Spring Cloud Gateway关于不显示API管理及请求链路的坑附带解决方案