Rails 延迟工作和 docker:添加更多工人

Rails delayed job and docker: adding more workers

我 运行 我的 rails 应用使用 Docker。延迟的作业由单个工作人员处理,该工作人员 运行s 在一个名为 worker 的单独容器中,工作人员 运行s 在其中使用命令 bundle exec rake jobs:work.

我有几种类型的作业,我想将它们移至单独的队列并为此创建一个单独的工作程序。或者至少有两个工人来处理流程任务。

我尝试 运行 我的工作容器 env QUEUE=default_queue bundle exec rake job:work && env QUEUE=another_queue bundle exec rake job:work 但这没有任何意义。它不会失败,会启动但不会处理作业。

有没有办法在一个容器中有不同的工人?它是正确的吗?或者我应该为我想要制作的每个工人创建单独的容器吗?

提前致谢!

运行 命令 command1 && command2 导致仅当 command1 完成时才执行 command2。 rake jobs:work 永远不会终止,即使它已经执行完队列中的所有作业,所以第二个命令永远不会执行。

一个“&”可能就是您要查找的内容:command1 & command2。 这将 运行 命令在它们自己的进程中独立。

您应该在生产环境中使用 delayed_job 脚本,最好将不同队列的工作人员放入不同的容器中,以防其中一个队列包含占用大量资源的作业。

这将为 default_queue:
启动延迟作业工作器 bundle exec script/delayed_job --queue=default_queue start
对于 Rails 4,它是:bundle exec bin/delayed_job --queue=default_queue start
查看有关该主题的答案:

您还可以使用 -n 选项在单独的进程中启动多个工作程序。这将在不同的进程中启动 3 个工人,所有从 default_queue:
中挑选工作 bundle exec script/delayed_job --queue=default_queue -n 3 start

rake jobs:work 和 delayed_job 脚本之间的差异:
似乎唯一的区别是 rake jobs:work 在前台开始处理作业,而 delayed_job 脚本创建一个在后台处理作业的守护进程。您可以使用更适合您的用例的那个。
检查此 github 问题:https://github.com/collectiveidea/delayed_job/issues/659

实际上,我刚刚在 docker

上缩放 delayed_jobs 时遇到了这个问题

请参阅此要点以获取脚本,该脚本使用任意参数启动延迟的作业并侦听 SIGTERM 并在容器关闭时平滑关闭已启动的作业。这样你就可以执行任意数量的进程和队列。

https://gist.github.com/jklimke/3fea1e5e7dd7cd8003de7500508364df

#!/bin/bash

# Variable DELAYED_JOB_ARGS contains the arguments for delayed jobs for, e.g. defining queues and worker pools.

# function that is called when the docker container should stop. It stops the delayed job processes
_term() {
  echo "Caught SIGTERM signal! Stopping delayed jobs !"
  # unbind traps
  trap - SIGTERM
  trap - TERM
  trap - SIGINT
  trap - INT
  # end delayed jobs 
  bundle exec "./bin/delayed_job ${DELAYED_JOB_ARGS} stop"

  exit
}

# register handler for selected signals
trap _term SIGTERM
trap _term TERM
trap _term INT
trap _term SIGINT

echo "Starting delayed jobs ... with ARGs \"${DELAYED_JOB_ARGS}\""

# restart delayed jobs on script execution
bundle exec "./bin/delayed_job ${DELAYED_JOB_ARGS} restart"

echo "Finished starting delayed jobs... Waiting for SIGTERM / CTRL C"

# sleep forever until exit
while true; do sleep 86400; done