把社区发帖接口对接进现有系统时,我差点被"用户已登录"这五个字逼疯

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
站长杂谈 159 浏览 0 回复

上周接了个需求,要把社区的发帖、回帖、积分变动三个模块接到客户的老系统里。听起来就是调几个接口的事,结果我在"用户登录态"这个环节卡了整整两天。

客户系统用的是自研的 SSO,我们社区这边是 JWT。两边各自跑都没问题,一打通就各种"登录态丢失"。用户明明在老系统点了个"去发帖",跳过来变成游客;发完帖回去,老系统又提示重新登录。两边用户表结构还不一样,一个用 `uid` 一个用 `user_id`,我中间加映射表的时候写反了字段,调试日志里看着一切正常,就是查不到人。

最后定的方案是:老系统跳转时带个加密 token,社区这边用 Redis 做三分钟短缓存,换发自己的 JWT。关键是这个 token 里要塞什么——塞太多怕泄露,塞少了不够用。我最后塞了 `source_uid`、`timestamp`、`nonce` 三个字段,签名校验用 HMAC-SHA256,密钥两边各存一半,组合的时候按固定顺序拼接。听起来稳妥,实现时我把拼接顺序写死在代码里,结果对方运维更新配置改了顺序,线上直接炸了一小时。

回帖接口更折腾。客户要求"回复后实时通知",我一开始想走 WebSocket,但老系统那边没这基础设施。退而求其次用了轮询,前端每十秒刷一次未读数,结果高峰期 Redis 的 `zrevrange` 被打到 CPU 飙高。后来改成发帖时往消息队列丢一条,老系统那边消费后写自己的通知表,社区这边只管发。两边数据不同步的问题靠对账脚本兜底,每天凌晨跑一遍,差异超过十条就告警。

积分接口是最顺利的,也是最坑的。社区这边积分变动有十几种场景:发帖、回帖、被点赞、被采纳、连续签到……客户只要其中四种。我图省事在回调里写了个 `if in_array($type, [...])` 就转发,结果对方接收端没做幂等,网络抖动时重复发了三笔,用户积分凭空多了。最后加了数据库唯一索引 `(source_id, type, created_at)`,配合 Redis 分布式锁,同一秒内相同来源的积分变动直接丢弃。对方技术负责人后来跟我说,他们之前被这个坑过,没提前提醒我是因为"想看看你们会不会踩"。

现在回头看,这三个接口最耗时间的都不是业务逻辑,是边界情况:超时怎么算、失败重试几次、两边数据对不上谁为准、用户注销了怎么处理历史记录。我把这些整理成了一份《对接 checklist》,第一条就写着:"先问对方有没有坑过你,再问对方有没有被坑过。"

评论0
回复 · 0
还没有回复
微信客服 微信客服