关于java:一个奇葩的线上问题导致我排查了一天

36次阅读

共计 2438 个字符,预计需要花费 7 分钟才能阅读完成。

昨天线上又出了个问题,花了一天的工夫才找到起因,说起来起因其实特地的坑爹啊。

事件是这样的,最近咱们上线了一个刷新用户 token 的性能,也就是 APP 里常常有的,只有你常常操作,就能让你始终放弃在线状态,不必始终从新登录,需要就是这么一个并不简单的需要,也很快的上线了。

然而上线之后发现了一个用户在某段时间继续长达 15 天没有调用过刷新 token 的接口,还始终放弃在登录状态(默认 token 生效是 7 天),这个就很奇怪了。

因为我并不是次要的开发,我是负责帮助考察起因。

依据开发的口述,我失去的信息如下:

  1. 依据数据库日志发现,用户在 8 月份只登录了两次,两次工夫距离有 15 天之长,另外排除了日志失落的问题,登录这个日志是同步保留并且在一个事务内的,不存在失落的可能。
  2. 依据 ELK 网关日志发现,用户在这 15 天之内,基本上每天都会应用 APP,而且都还是须要登录的接口。
  1. 依据 ELK 用户服务日志发现,用户并没有在这段时间内刷新过 token,依照情理应该在 7 天后过期,然而却继续了 15 天。

以上的状况,我基本上都看到了,也一一验证过,的确状况就是这样。

那么,咱们排查的方向也就确定到,是不是有其余的 BUG 导致用户的 token 会续期的问题?按说如果是这样的话,那么这个问题应该早就存在很久了,不可能等到这个需要上线才呈现,也从未看到过任何这方面问题的反馈。

于是,我筛查了一部分用户的日志,发现登陆其实都挺有法则的,大部分状况都会在 <=7 天的工夫有一次登陆,超过 7 天的状况看日志也发现是没有接口调用的,大略阐明了这个问题是没有呈现过的。

难道是这次的上线导致的 bug?

于是征询了 QA 相干的测试状况以及开发提供的最近线上调用的日志和状况来看,没有什么问题。

于是,我还特意去翻看了一遍代码,放心有 BUG 导致给 token 续期了,然而排查后有没有发现问题。

至此,排查如同陷入了僵局,于是只能从其余方面找思路。

我询问了对于整个业务的调用链路,简略来说就是用户登录的时候去申请 token,而后保留下来,当前每次申请的时候都带上 token,而后鉴权的服务会去校验 token 的有效性。

那么,我不禁狐疑,难道鉴权的服务存在什么问题???

于是又苦哈哈地排查了一遍鉴权服务的代码,发现代码写的十分垃圾,token 的保留写的到处都是,得有 10 几个调用的中央。

通过 CAT 排查了一遍这些接口,发现其实大部分的接口最近一个月都没有调用,和开发也确认了一下,这些接口根本都是老接口,曾经没有用了。

只有一个有存在调用的中央,也就是咱们当初用的鉴权,这个中央只是简略的去 redis 中判断一下 token 是不是存在,在本地和测试环境中也去验证了一把,并没有发现问题。

OK,到此为止,工夫也曾经到了下午了,包含我在内的几个排查人员曾经快要炸了,这个问题曾经找了快一天了,没有发现任何问题,整个事件也就陷入了停滞状态。

我默默地点了根烟,你还别说,小苏还真是好抽的很(情谊揭示,抽烟无害身体健康)。

我不禁想到以前 leader 说,我以前他么就不抽烟,而后组里其余几个人每次查问题查不到起因,就跑出去抽烟,后果一回来他们说问题找到了,于是我不得不也抽烟。。。

所以怎么说,抽烟能给人带来思路啊。

我不禁想到一个问题,他们说的只是他们说的,尽管我看了他们给我的演示,然而,我除了看到了用户的登录日志,和他们给我看到的网关日志、服务调用的日志之外,我其实并没有去本人去验证他们的说法。

于是,我先从数据库查看了登录日志,发现这个的确没问题,代码验证过,的确在登录的事务之内,尽管这个代码写的很垃圾,框了整个登录逻辑,然而这个事务这时候缺他么额定的保障了这个日志的存在的必要性!

我接着看网关日志,发现也没什么问题,用户的鉴权接口根本在始终调用,然而在 7 天之后也都通过了,并没有提醒 token 生效等状况。

于是我再接着看服务自身的调用日志,之前他们给我看的时候,就是这样一个后果,依据日志信息和用户 ID 没有找到日志,因而排除了用户调用过刷新 token 接口的状况。

这里我隐隐感觉到不对劲,于是,我换了一个搜寻形式,搜用户的设施信息,不搜用户 ID!!!

后果尼玛呈现了!!!搜寻到了后果,用户在两头调用过一次刷新 token,看了下工夫,第一次登陆 8 月 8 号,8 月 23 号又登陆了一次,15 号刷新了一次,工夫刚好吻合,7 天!

事件到这里也基本上水落石出了,并不是有什么鸡毛的 BUG,纯正就是我置信了他们的排查后果并且没有去验证!在谬误的排查路线上越走越远了我!

真尼玛是炸裂!

OK,到这里不禁要想,为什么用用户 ID 搜不到后果?我把后果通知开发的时候,他也惊呆了,他说我搜其余用户 ID 能够搜到啊,说完还给我演示了一下。

我就测试了一下,发现的确能够,进一步测试了几个用户 ID,发现有的能搜到,有的不能搜到,这有点奇怪了。

认真看到了一下咱们的 token,发现 token.123.456bdf(两头的是用户 ID)这样搜是不搜不到的,token.456.bde123这样能搜到。

这应该是分词的问题了,数字连在一起被当做一个字符串分词了,所以存在有的能搜寻到,有的不能搜寻到,测试了一下发现状况的确是这样。

咱们能够本人测试一下 ELK 的分词成果,进入首页,而后抉择 ES API 交互。

验证一下咱们的猜想是不是因为分词的问题导致的,默认应该是规范分词,analyzer 抉择 standard,能够看到输入后果的确是 OK 的。

再换一个字符串,tokentest 前加上一点数字,分词的后果也的确如咱们猜想的那样。

解决方案的话有两个,第一个只能换一个分词器了,比方咱们如果用 pattern 正则分词器就能够达到咱们想要的成果,然而用啥分词这个咱们说了不算。

第二个办法其实能够换一个搜寻形式,比方 message: "*token*" and message:*123456* 这样也能搜寻到,只是你平时怎么会这样用呢,对吧。

总结一下,咱们平时在排查问题的过程中,肯定要本人入手,不要轻易置信他人说的状况,大胆假如,小心求证,方得善果。

正文完
 0