发送记录里 90% 停在 sending,用户说没收到,服务商后台显示 1200 封被拒,状态码 550,本地表里一条失败记录都没有。日志里能对上时间点,这种反而好排。

调用发信接口拿到 202 就当成投递成功,异步的失败回执没有回调地址接收,失败只留在服务商后台。发送表里也没有重试次数字段。这一点先确认清楚,后面就不用反复试。

ALTER TABLE mail_log
ADD attempts TINYINT DEFAULT 0,
ADD last_error VARCHAR(255) NULL,
ADD next_retry_at DATETIME NULL;

「发信回执缺失」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

别只看报错的最后一行,往上看几行,真正的起因通常在上面。

处理上按这个顺序:加回执回调接口,按消息 ID 更新最终状态;发送表补重试次数、最后错误、下次重试时间三列,失败可查可重试;每天对一次本地状态和服务商后台的失败数,差值超过 1% 就告警。

结果对不对很好判断,被拒的邮件在本地表里能看到 550 和重试时间,状态不再停在 sending。

作者 9823189