一笔订单状态变更,用户邮箱里躺着三封同样内容的邮件,站内信里还有一条,时间戳差了十几秒。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,邮件通知和站内信各挂了一个钩子,都监听同一个订单状态动作,谁也不知道对方发过。队列重试时又补发一次,去重标记写在内存里,重启就没了。
「通知渠道重复发送」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
$key = 'notify_' . $order_id . '_' . $status;
if (get_transient($key)) { return; }
set_transient($key, 1, DAY_IN_SECONDS);
cs_send_notifications($order_id, $status);
权限不要一口气开到最大,先加到够用再往上试,范围小才好收。
具体做法是,把通知收口到一个服务里,先写通知记录再分发渠道;用订单号加状态做去重键,发之前查一次;重试只重发失败的渠道,别整条重跑。
最后用这个标准收尾,再改一次订单状态,邮件只来一封,站内信只加一条。
