偶现外部接口调用token失效

背景

手里接到一个项目,项目存在大量外部页面接口调用(就是嵌入页面)。在获取对方页面链接前,我们需要获取token换取ticket拼接到网关的链接上。然后网关校验ticket是否在他们服务器的缓存中存在,如果存在这通过链接上的页面表示符参数,返回响应的页面给我们。大致如下图: 看了上图,你不是觉得很完美,没有问题了,还直喷没有技术含量。

问题

然后问题来了,有部分网速比较慢的用户反馈访问带三方页面的服务页面经常出现401或者400。这里400和401是对方封装的权限异常,也就是ticket、token这些有问题。

过程

一开始没有头绪,我们坚持认为我们获取token是成功的,tikect也是成功的,传递过去的参数为什么你们会说权限无效?对!肯定是他们问题,他们有毒! 就在这样的怀疑下,安心的有过了一个星期,晚上谁的挺香。 但是运营扛不住了,隔三差五反馈用户有反馈了,你们技术行不行啊。 领导直接对我发话,这个问题你不要让开发自己去看,你作为技术经理你要参与分析。 呵呵,我分析了我就觉得是那帮吊炸天的人有问题。 领导来一句你考虑了时间差了吗?

分析

领导不亏是领导,就是牛皮plus,他这一说画了个草图,我才知道自己的见识有多浅薄。 不说了上图: 上图中的'产生ticket2,并存入ticket1'是笔误,应该是'产生ticket2,并存入ticket2'

原因

远程调用我们忽略两个因素:

复制代码
   用户多次点击,无论是用户手贱还是网络问题,这是客观存在的,我们没有考虑到;
   更没有考虑到的是多次请求的时延性,特别在调用外部系统的情况下;

解决

问题找到了,原因也分析清楚了,方案就好做了。

  1. 作为请求方,我们token请求太频繁,因此增加token缓存过期时间设置为30分钟。在每次请求进来时检查token过期时间,如果不到两分钟的时候,再次去网关获取token。

  2. 上一步只能解决不频繁去获取token的问题,关键解决这个问题是,需要在同一个用户获取网关token时需要在redis缓存中增加分布式锁,防止在第一次获取token或者在更新的时候出现之前时序问题。

  3. 前端优化,增加每一次请求后增加loading遮罩层,特别是容易出现时序问题的这些业务上,也为了防止其他类似因为网络慢而发起的多次请求。也能一定层度上降低正常用户的幂等性相关问题,特别是后端比较懒或者没有考虑幂等性问题的时候。

    解决后大致如下图:

回顾

以上问题真的就解决了吗?不一定还有个问题要考虑。 使用相同的token获取的ticket是否每次都一样,如果不一样,还会出现同样的问题。 解决方法,改为缓存ticket,并加锁?但是页面访问是一次性的,基本不会用第二次。那对获取token和获取ticket整个作为一个整体事务是否可以?我觉得可以。

总结

干了11年的IT,遇到生产上的20%问题多和网络有关,特别是现在分布式微服务。网络问题会导致主从节点频繁切换,还会导致出现服务孤岛,还会出现因分布式事务导致数据不一致,也有可能出现想本文一样因为时延而产生的幂等性问题。

如果本文有什么错误或纰漏欢迎指出一起讨论。

相关推荐
考虑考虑24 分钟前
Sentinel安装
java·后端·微服务
IT_陈寒28 分钟前
SpringBoot自动配置失灵?你可能忘了这个关键注解
前端·人工智能·后端
碎碎念_49230 分钟前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端
逝水无殇1 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#
YIAN1 小时前
从手写 Agent 工具到 MCP 协议:一文搞懂大模型跨进程跨语言工具调用
后端·agent·mcp
小兔崽子去哪了2 小时前
Docker 删除镜像后磁盘空间没有释放?
后端·docker·容器
高明珠2 小时前
麒麟 V10 SP1 排查实录:ttyS5 每 10 秒莫名收到一批报文,元凶是 eGTouchD
后端
卷无止境2 小时前
Python FFI 技术深度解析:ctypes、cffi 与 pybind11 的性能差异与实践挑战
后端·python
ServBay2 小时前
AI Gateway 是什么?为什么每个平台都在做
后端·aigc·ai编程
SamDeepThinking3 小时前
Vibe Coding最重要的是Spec
后端·程序员·ai编程