OAuth2 鉴权接口在 5 万并发下 token 失效,如何定位是 JWT 解析还是 Redis 瓶颈
解读
面试官把“5 万并发”与“token 失效”两个关键词同时抛出,核心想考察三件事:
- 能否把“并发高”与“失效”之间的因果关系拆成可量化的技术指标;
- 能否在 Java/Go 主流技术栈下,用最低成本、最快速度把“JWT 解析慢”与“Redis 访问慢”区分开;
- 能否给出国内落地可复制的监控、压测、根因定位三板斧,而不是背八股文。
因此,回答必须体现“指标→证据→结论”的闭环,并给出 10 分钟内可落地的排查脚本与阈值标准。
知识点
- OAuth2 授权码模式访问链路:网关→鉴权服务→JWT 解析→Redis 检查 refresh_token 黑名单→返回 200/401。
- JWT 解析 CPU 热点:JJWT/nimbus 的 RSA256 验签、Claims 反序列化,单核 QPS 上限约 1.2 万,超线程抖动后骤降。
- Redis 瓶颈模型:单分片 8 万 QPS 时 RTT 从 0.5 ms 涨到 2 ms,CPU 利用率 70% 为拐点;阿里云 8 G 主从版连接数上限 2 万,超过后新建连接排队。
- 国内常用监控:ARMS/SkyWalking 方法级剖析、Prometheus+Grafana Redis 面板、JVM Async-Profiler 火焰图、tcpdump 四元组抓包。
- 区分公式:
若 CPU 利用率↑ 且 JWT 解析线程占 CPU 前 3 名→JWT 问题;
若 Redis 慢查询>1 ms 占比>5% 或 ConnectionTimeout>200 ms→Redis 问题;
若两者同时出现→网关线程池耗尽,需横向扩容。
答案
现场回答采用“3 分钟定位法”,分四步输出证据链:
第一步,秒级止血
在网关 Nginx 层把 /oauth/verify 接口降级为“本地缓存 + 短 TTL”开关,保证 5 万并发用户不再 401,避免客诉。
第二步,30 秒看大盘
打开 Grafana Redis 面板,重点看
- 瞬时 QPS:是否超过 8 万/分片;
- 连接数:是否持续大于 2 万;
- 99 RT:是否突刺到 5 ms 以上。
若三项任一飘红,初步锁定 Redis;若全部绿色,进入第三步。
第三步,2 分钟火焰图
在鉴权 Pod 内执行
kubectl exec -it auth-pod -- profiler.sh -d 60 -f cpu.html
用浏览器打开 cpu.html,搜索关键字“parseClaimsJws”或“RSAPublicKey”,若占比>30%,即可判定 JWT 解析是热点;否则热点在 Netty/Redis Lettuce 连接处。
第四步,1 分钟压测复现
用 Gatling 在本地起 50 线程固定 5 万 RPS,分别打
A 场景:只验签不回 Redis;
B 场景:跳过验签只读 Redis。
对比 99 RT:
- A 场景 RT 从 8 ms 涨到 80 ms→JWT 瓶颈;
- B 场景 RT 从 2 ms 涨到 20 ms→Redis 瓶颈。
结论交付
把以上四张截图(Redis 面板、火焰图、A/B 压测报告、Nginx 401 数)贴进飞书文档,给出“瓶颈在 Redis 连接数超限,需把主从版升级成 16 分片集群,并开启本地缓存预热”即可闭环。
拓展思考
- 如果 JWT 采用 ES256 而非 RSA256,CPU 消耗下降 45%,但国内国密合规场景需改用 SM2,此时验签性能与 RSA 接近,需要提前在性能基线里预埋国密压测模型。
- Redis 瓶颈若因大 Key 导致,单 Key 超过 10 KB 时网络往返会放大 3 倍,可通过“SCAN+MEMORY USAGE”定期巡检,并把黑名单结构从 String 改成 BloomFilter,内存降 90%,QPS 上限提到 25 万。
- 5 万并发仅是入口压力,实际 JWT 解析次数可能因网关层本地缓存命中降到 1 万,需要把“缓存命中率”纳入 SLA,低于 85% 即触发 P1 告警,避免再次误判。