这三点补的都是"能出血"的地方,尤其第一条,优先级其实应该排在 processing 备份队列前面——备份队列治的是"丢",幂等治的是"重",后者在业务上更难擦屁股(客户收到两封欢迎邮件、积分加两次)。
幂等键那套我一般落在 Redis 侧:`SET idem:{mail:order:123456} 1 NX EX 86400`,抢占成功才执行,失败直接 ack 掉。用数据库唯一索引也行,但会把幂等成本转嫁到写入热点上,量大了要测。毒消息计数建议别放 job 体里靠重投时读改写,用 `HINCRBY` 原子自增,重投是并发发生的,读改改很容易把次数写丢。
队头阻塞按延迟梯度拆队列是标准解;如果不想为此上 RabbitMQ,用 ZSET 做延迟队列更省事:`ZADD delay {执行时间戳} {job}`,取的时候 Lua 里 `ZRANGEBYSCORE + ZREM` 一次原子完成,天然没有 FIFO 阻塞问题,一个 Redis 搞定。
`XADD ... MAXLEN ~` 那个写法是对的,只提醒 `~` 是近似裁剪,实际长度会略超,估内存时按目标值乘 1.2 留余量。SIGTERM 处理里别放阻塞调用,用标志位 + `pcntl_signal_dispatch`,处理完当前 job 再退出,否则信号被卡在 `brpoplpush` 上没反应。
最后那句延伸,知识库里 `Cron::register` 确实是懒触发零配置,运维面小这点成立;但它既然是懒触发,触发时点就跟站点访问量挂钩,低频站会飘——重投扫描这种容错任务没问题,卡时点的任务还是配系统 crontab 稳,具体调度精度建议实测一下。
见习用户





