第十一章:AccessToken 管理与企业微信稳定发送机制

这一章开始,我们从“能跑的系统”进入:

生产级系统必须解决的稳定性问题


11.1 当前系统的隐患

在上一章,我们实现了:

Worker → DeepSeek → 企业微信发送

但有一个非常严重的问题:


❌ 现有 AccessToken 方案问题

当前实现是:

每次发送消息都调用 gettoken

问题如下:

1️⃣ 性能浪费

每条消息 → 请求一次微信API

2️⃣ 容易触发限流

企业微信限制:

频繁调用 gettoken 会被限制

3️⃣ 不稳定

网络抖动 → token 获取失败 → 全链路失败

11.2 正确方案:Token缓存机制

📌 架构设计

WeCom API
Token Manager
Redis缓存
Worker发送消息

11.3 Token生命周期规则

企业微信 Token:

有效期:7200秒(2小时)

但实际必须:

提前10分钟刷新

11.4 Redis Token结构设计

Key:
wecom:access_token

Value:
{
  "token": "...",
  "expire_at": 1234567890
}

11.5 Token Manager设计

📌 新增模块

app/core/token_manager.py

📌 完整实现

import time
import json
import httpx
import os
from app.queue.redis_client import redis_client


class TokenManager:

    def __init__(self):
        self.corp_id = os.getenv("WECOM_CORP_ID")
        self.secret = os.getenv("WECOM_SECRET")

        self.redis_key = "wecom:access_token"

    async def get_token(self):

        # 1️⃣ 先查Redis
        cached = redis_client.get(self.redis_key)

        if cached:
            data = json.loads(cached)

            # 未过期直接返回
            if data["expire_at"] > time.time():
                return data["token"]

        # 2️⃣ 重新获取
        token = await self.fetch_token()

        return token

    async def fetch_token(self):

        url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"

        params = {
            "corpid": self.corp_id,
            "corpsecret": self.secret
        }

        async with httpx.AsyncClient() as client:
            resp = await client.get(url, params=params)
            data = resp.json()

        token = data["access_token"]
        expires_in = data.get("expires_in", 7200)

        expire_at = time.time() + expires_in - 600  # 提前10分钟刷新

        # 存Redis
        redis_client.set(
            self.redis_key,
            json.dumps({
                "token": token,
                "expire_at": expire_at
            })
        )

        return token

11.6 企业微信发送服务升级

📌 wecom_service.py(改造版)

import httpx
import os
from app.core.token_manager import TokenManager


class WeComService:

    def __init__(self):
        self.agent_id = os.getenv("WECOM_AGENT_ID")
        self.token_manager = TokenManager()

    async def send_message(self, user: str, content: str):

        token = await self.token_manager.get_token()

        url = f"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}"

        payload = {
            "touser": user,
            "msgtype": "text",
            "agentid": self.agent_id,
            "text": {
                "content": content
            }
        }

        async with httpx.AsyncClient() as client:
            resp = await client.post(url, json=payload)
            return resp.json()

11.7 Worker接入优化

Worker无需改逻辑,只保持调用:

send_message(user, reply)

11.8 Token机制运行流程

Worker请求发送
TokenManager.get_token()
Redis是否存在?
   ↓ yes → 直接返回
   ↓ no
调用企业微信 gettoken
写入Redis
返回Token

11.9 系统稳定性提升

✔ 改造前

每次请求 → gettoken API

✔ 改造后

99%请求 → Redis读取
1%请求 → 刷新token

11.10 性能对比

📊 改造前

延迟:200~500ms(每次请求)
稳定性:低
风险:限流

📊 改造后

延迟:<5ms
稳定性:高
风险:极低

11.11 当前系统架构(生产级)

企业微信
FastAPI
Dispatcher
Redis Queue
Worker
DeepSeek
WeCom Service
TokenManager (Redis缓存)
企业微信API

11.12 当前系统能力总结

✅ 已完成能力

✔ AI对话能力
✔ 异步队列
✔ Worker模型
✔ DeepSeek接入
✔ 企业微信发送
✔ AccessToken缓存
✔ Redis稳定性

11.13 本章核心价值

这一章完成后:

👉 系统从“能用”
升级为
👉 “生产级稳定系统”

🚀 下一章预告(第十二章)

第十二章:企业微信消息完整闭环优化(可靠性与重试机制)

下一章我们将解决生产环境真正的问题:

❌ 消息丢失
❌ Worker失败
❌ AI超时
❌ 重复消息
❌ 网络波动

下一章核心内容:

✔ 重试机制(Retry)
✔ 幂等设计(MsgId)
✔ Dead Letter Queue
✔ Worker异常恢复
✔ 消息去重

👉 到这一章结束:

系统将具备真正的:

“企业级可靠消息处理能力”