【发布时间】:2018-04-21 13:36:06
【问题描述】:
我正在使用 Laravel 5.5,并且正在尝试设置一些快速队列处理。我遇到了一个又一个的障碍。
本网站是一个雇主/雇员匹配服务。因此,当雇主发布工作职位时,它需要遍历我们系统中的所有员工并计算一些变量以确定他们与工作的匹配程度。我们已经把这一切都弄清楚了,但是当系统中有数千名员工时,一次处理一个需要很长时间。所以,我准备写几个表。第一个是定义职位 ID 和状态的简单表。第二个是列出所有员工 ID、职位 ID 和正在处理的员工状态的表格。只需几秒钟即可编写,然后允许用户在应用程序中继续前进。
然后我有另一个服务器设置,每分钟运行一个 cron 来检查第一个表中的新条目。找到后,它会将其标记为已启动,然后抓取所有员工并遍历每个员工并在 Laravel 中开始排队的工作。我定义的作业确实正确提交到队列并运行queue:work 实际上确实正确处理了作业。这一切都经过测试。
但是,我遇到的问题是我已经尝试了数据库 (MySQL)、Redis 和 SQS 用于队列,它们都非常慢。我正在使用同一台服务器尝试操作queue:work(使用Supervisor并尝试运行多达300个进程),但随后创建了3个不运行cron但只运行Supervisor(每个克隆100个进程)的克隆并被杀死第一台服务器上的主管。使用数据库它会处理得很好,虽然运行 10k 个排队的作业需要几个小时,但是使用 SQS 和 Redis 我会遇到很多失败。脚本花费的时间太长或其他什么。我检查了运行 worker 的克隆上的 CPU,它们几乎没有达到 40%,所以我没有对服务器过度征税。
我刚刚阅读了有关 Horizon 的信息,但我不确定它是否有助于解决这种情况。我一直在尝试查找有关如何使用 Laravel 正确设置队列处理系统的信息,但遇到的问题多于答案。
有没有人熟悉这些东西并对如何正确设置它有任何建议,以便它非常快速且无故障(假设我的代码没有错误)?
更新:根据其他一些帖子建议,我想我会分享更多细节:
- 我使用 Forge 作为设置工具,它带有 2G RAM 的 AWS EC2 服务器。
-
三个克隆中的每一个都具有以下工作器配置:
command=php /home/forge/default/artisan queue:work sqs --sleep=10 --daemon --quiet --timeout=30 --tries=3 process_name=%(program_name)s_%(process_num)02d autostart=true autorestart=true stopasgroup=true killasgroup=true user=forge numprocs=100 stdout_logfile=/home/forge/.forge/worker-149257.log 数据库在 Amazon RDS 上。
我很好奇 Laravel 缓存是否可以与队列系统一起使用。排队脚本的元素对于每次运行都是通用的,所以如果我从一开始就将这些数据排队,它可能会节省一些时间。但我不相信这会是一个巨大的进步。
【问题讨论】:
-
通过查看问题描述和复杂性,我建议您将问题发布到 larachat slack 团队。如果您找到了答案,请在此处发布。
-
我在 Laravel 中没有这样做的经验,但几年前我们有一个 PHP 项目在工作,它使用
beanstalkd作为消息队列,每小时愉快地执行数百万个任务。如果执行 10.000 个任务需要数小时,可能是您的匹配算法太复杂或性能不够? -
Andrew,您发现 Redis/SQS 后端有哪些错误?您在
queue:work上使用--timeout=30,这意味着作业将在 30 秒后中止。在一个盒子上同时运行一堆繁重的作业(100 似乎有点高),它们可能会超时。
标签: php laravel queue laravel-5.5 laravel-horizon