You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Horizon处理mailcoach-feedback过慢(每分钟1任务)如何排查修复?

问题根因定位

你遇到的性能瓶颈核心是MySQL对JSON字段的无索引查询导致的,既不属于Mailcoach的设计缺陷,也不是核心配置错误:

  • 你排查到的慢SQL对webhook_calls表的payloadJSON字段直接用JSON_EXTRACT提取MessageId做过滤,没有对应索引的情况下,MySQL每次查询都要做全表扫描,逐行解析JSON内容,表数据量越大耗时越长,单核心CPU会被这类计算直接占满。
  • 你将队列进程提升到10只会加剧问题:多个进程同时触发慢查询,CPU资源被占满后所有队列任务都会排队阻塞,处理速度自然无法提升。
修复方案

临时缓解措施

  • 先将mailcoach-feedback队列的进程数降回1~2,避免大量慢查询争抢CPU资源导致整体服务雪崩
  • 清理webhook_calls表中超过30天的历史无用数据,降低表总数据量可以临时降低查询耗时
  • 给服务器添加1GB大小的Swap分区,缓解内存不足导致的MySQL性能下降

永久修复方案

  1. 给JSON字段的MessageId添加生成列和索引
    执行以下SQL即可,不需要修改Mailcoach的业务代码,MySQL查询优化器会自动将原JSON字段查询匹配到新索引上:
-- 添加存储类型的生成列,自动同步JSON中的MessageId值
ALTER TABLE `webhook_calls`
ADD COLUMN `message_id` VARCHAR(255)
GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(`payload`, '$.MessageId'))) STORED;

-- 给生成列添加普通索引
CREATE INDEX `idx_webhook_calls_message_id` ON `webhook_calls`(`message_id`);

加完索引后原慢SQL的耗时会降到毫秒级,CPU占用会直接回落。

  1. 优化Horizon配置
  • 单核心服务器的Horizon总进程数不要超过3个,进程过多会因为CPU上下文切换反而降低性能
  • 将mailcoach-feedback队列的timeout参数从600调整为60,避免异常卡住的进程长期占用资源
  • 把队列进程的memory参数调整为256,避免PHP进程因为内存不足被意外杀死
  1. 长期优化建议
  • 定期清理webhook_calls表的历史数据,建议保留不超过90天的webhook记录
  • 开启MySQL慢查询日志,定期巡检未加索引的慢查询
  • 如果后续邮件发送量持续提升,建议升级到2vCPU配置的服务器,PHP队列和MySQL都对CPU资源比较敏感。

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 14:18:02