安卓推送成功率从 92% 掉到 65%,FCM 返回的错误里 UNREGISTERED 占了七成。token 表里有 40 万条记录,最近三个月活跃的只有 12 万。日志里能对上时间点,这种反而好排。

应用卸载或重装后旧 token 立即失效,服务端没在收到 UNREGISTERED 时删除记录。每次群发都对这些死 token 重试一遍,失败率被拉高。表越来越大,查询也变慢。这一点先确认清楚,后面就不用反复试。

DELETE FROM push_token WHERE last_active < now() - interval '90 days';
-- 单条失效清理
DELETE FROM push_token WHERE token = 'cXYZ...';

「推送 token 失效」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。

处理上按这个顺序:收到 UNREGISTERED 或 INVALID_ARGUMENT 就删掉对应 token;按 last_active 定期清理 90 天未活跃的记录;发送前按平台和版本过滤 减少无效请求;统计成功率时剔除已失效 token 再算。

结果对不对很好判断,清理后推送成功率回到 90% 以上,群发请求量少了三成,token 表行数降到 15 万。

作者 9823189