• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

使用sentinel 遇到的坑

武飞扬头像
liuec1002
帮助2

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/版本说明

用户权限的问题

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbhjjf
系列文章
更多 icon
同类精品
更多 icon
继续加载