再见二丁目 | yitimo的个人日志

再见二丁目

在eggjs中管理微信token

发布于: 2020-06-12 15:32

此文章久未修订,请自行甄别内容准确性。

本文基于eggjs的多进程来梳理如何妥善管理会失效的第三方token(如微信平台accessToken)。

eggjs运行后会有3种进程在工作:

  1. master进程 统筹整个应用, 只做顶层调度工作, 如果master挂了, 即代表应用挂了
  2. agent进程 做一些必须单例进行的工作, 比如写本地文件, 比如请求获取最新的外部访问令牌(如果让worker来做那不同worker的最新token会相互冲突)
  3. worker进程 做日常业务, 可以支持高并发, 可以复制多个一起工作, 其中一个挂了或在工作中就换另一个

微信开发

微信服务的接口调用大都依赖一个会失效的的访问令牌(accessToken), 这个token一般过期时间为2小时, 并且存在一个机制:

当token快过期时, 可以请求获取最新的token, 这时新老token都有效, 老token5分钟后失效。

此时如果我们简单的在代码中维护这个token的话会遇到一些问题:

正确使用

为了不让多个worker进程的accessToken相互冲突, 必须只由单个进程来做token更新的工作, 并同步给所有的worker进程, 保证大家都能使用同一份最新的token。

比较合适的就是在agent进程中做这件事:

  1. agent进程维护accessToken和过期时间, 并同步给所有worker(发消息)
  2. worker发现token已经快过期, 发消息通知agent, agent更新token并再次同步给所有worker
  3. 可能会有多个worker同时通知agent需要更新token, 要做好保护, 利用好新老token可共存5分钟这个特性

使用定时任务

在由worker主动通知agent来更新accessToken的基础上, 还可以增加定时任务来更新accessToken, 比如定时每10分钟检查一次token是否快过期了, 如果快过期了就随机指派一个worker进程进行更新, 并同步给所有worker。

终极方案

终极方案

一定要这么做吗

mysql

mysql数据库本身支持多个连接, 所以应用大可以给每个worker都建立一个到mysql的连接, 这样可以提高数据库操作效率。

总结