Token高并发解决方案
一:作为token使用的第三方 客户端模式使用token
可以采用单例模式或定义一个全局变量isRefresh 标志,加同步锁Synchronized来保证token过期的那个时间点,刷新token方法只被调用一次。
二:作为token服务器端:
后端方案:利用 Redis 缓存
当同时发起多个请求时,第一个接口刷新了 Token,后面的请求仍然能通过请求,且不造成 Token 重复刷新。那么,后端在用户第一次登录时,需要将生成的 Token 数据(token 和 createTime)缓存一份到 Redis 中。
当 Token 过期时,重新生成新的 Token 数据并更新 Redis 缓存,同时在 Redis 中设置一条 Token 过渡数据并设置一个很短的过期时间(比如 30s)。如果后面的请求发现 Token 已经被刷新了,就判断 Redis 中是否存在 Token 过渡数据,存在就放行,这样同一时间的请求都可以通过。
后端使用Redis
解决
同时多个接口请求,第一个接口刷新了 Token
,后面的请求还是携带的刷新前的旧 Token
。
后端要解决这个情况,应该再添加一个刷新 Token
的过渡期,在刷新 Token
的时候,在 Redis
同时设置一条过渡期数据,视情况设置 15S
过期(这个时间看情况设置),然后认证的时候先判断这个 Token
是不是还在过渡期内,是的话就直接放行通过。
大概的意思的刷新Token
后,应该再添加一个刷新 Token
的过渡期,在 Redis
同时设置一条过渡期数据,设置 15S
过期(这个时间看情况设置),然后首先判断下Redis
中是否存在这个Token
,存在就放行,这样同一时间的请求就都可以通过了。
前端解决方案:
前端使用axios解决
同时发起多个请求时,其他接口如何重试,两个接口几乎同时发起和返回,第一个接口会进入刷新 Token
后重试的流程,而第二个接口需要先存起来,然后等刷新 Token
后再重试。同样,如果同时发起三个请求,此时需要缓存后两个接口,等刷新 Token
后再重试。由于接口都是异步的,处理起来会有点麻烦。
当第二个过期的请求进来,Token
正在刷新,我们先将这个请求存到一个数组队列中,想办法让这个请求处于等待中,一直等到刷新 Token
后再逐个重试清空请求队列。
那么如何做到让这个请求处于等待中呢?为了解决这个问题,我们得借助 Promise
。将请求存进队列中后,同时返回一个 Promise
,让这个 Promise
一直处于 Pending
状态(即不调用 resolve
),此时这个请求就会一直等啊等,只要我们不执行 resolve
,这个请求就会一直在等待。当刷新请求的接口返回来后,我们再调用 resolve
,逐个重试。
参考文章:
关于token的总结和思考——并发访问刷新策略,jwt过期及作废问题
JWT生成token及过期处理方案
Token 刷新并发处理解决方案