据微信公众平台官方开发文档描述,token的有效期为7200秒,且不会随着调用接口而自动更新过期时间,那么token就有过期的可能,需要我们在token过期之前刷新。
在token未过期之前,调用接口获取token并不一定会返回相同的token,如下图所示测试用例,每隔三秒调用一次接口,结果显示每次获取的token都不相同。
官方文档推荐我们使用一台“中控机”管理token,其它需要用到微信token的应用都应该通过调用中控机提供的接口获取,避免多个应用同时刷新token。
文档还描述,微信公众平台系统限定token的更新频率,每次更新token,微信公众平台都会保留上一个token在5分钟内可用。但如果多个应用都去更新token,将会导致token频繁失效、频繁更新。
举个例子:应用A在发起请求时,发现token过期,然后将token刷新并缓存到本地,5分钟后,应用B缓存的token就会失效,当应用B发起请求时,发现token失效,于是又更新一次token,应用A缓存的token又会在一5分钟时间后失效。如此反复,token就会被频繁更新。
当然,如果请求微信平台接口的需求场景不多且并发量不高,微信平台提供的刷新频率和老token的过期策略是足以够用的。
因此,我们采用官方文档的建议,只让一个应用管理token的更新,将该应用作为“中控机”,其它应用访问该应该获取token。并要求中控机应该做到:确保其它应用每次都能从中控机获取到有效的token。
为达到目的,中控机需要实现:
- 如果“中控机”应用是集群分式部署,则应该通过分布式锁控制同时只更新一次token;
- 应用启动时应该获取一次token,并记录token的过期时间;
- 其它应用请求获取token时,根据token过期时间判断token是否已经失效,如果token过期则刷新token;
- 应用应该定时的,在token过期之前刷新token,避免其它应用请求token时发现token过期,从而避免多个应用阻塞等待获取新的token。
其它应用应该缓存token吗?
为提升性能,应尽量避免每次请求微信公众平台的接口都需要先从“中控机”获取微信token,所以其它应用可以缓存token。
在中控机确保每次请求都能获取到有效token的前提条件下,其它应用可将token缓存在内存中,当请求微信接口响应token无效时可重新从中控机获取token并重试请求(其它应用不需要加锁获取)。
同时,我们还可以利用微信公众平台系统为老token提供5分钟可用期的策略,其它应用也可定时每五分钟内请求一次中控机更新本地缓存的token。这样就能大大减少其它应用使用到过期token的可能性,降低因token失效而重试的概率。
可能会犯的错:中控机提供获取token的接口支持其它应用强制刷新token,自身不负责token的刷新。
这样做的结果就是跟没有中控机没有多大区别,还是存在每个应用同时请求刷新token的问题。除非在接口加锁,但自身也应该定时刷新token,否则存在分布式锁的性能问题。
如果要这样做,其它应用还要放弃在本地缓存token,因为应用A请求刷新token应用B感知不到,这就导致应用B缓存的token是过期的,而应用B不能确保再次请求中控机获取到的是最新的token,为了保险起见,还得请求刷新token,如此一来,问题反反复复还是解决不了。