【问题标题】:Processes spawned by sidekiq are stopped when sidekiq stops当 sidekiq 停止时,sidekiq 生成的进程也会停止
【发布时间】:2017-11-21 16:11:38
【问题描述】:

我正在一项作业中进行一些处理,最终执行外部 shell 命令。该命令正在执行一个需要数小时才能完成的脚本。

问题是,在我使用 spawndetach 启动脚本后,如果我使用 kill -15 信号关闭 sidekiq 作业,脚本将停止执行。仅当 sidekiq 触发 spawn 命令时才会发生此行为 - 如果我在 irb 中执行此操作并关闭控制台,则不会发生此行为。所以不知何故,它似​​乎仍然绑定到 sidekiq - 但是为什么以及如何避免它呢?

test.sh

#!/bin/bash

for a in `seq 1000` ; do
  echo "$a "
  sleep 1
done

spawn_test_job.rb

module WorkerJobs
  class SpawnTestJob < CountrySpecificWorker
    sidekiq_options :queue => :my_jobs, :retry => false

    def perform version
      logfile = "/home/deployer/test_#{version}.log"
      pid = spawn(
        "cd /home/deployer &&
          ./test.sh
        ",
        [:out, :err] => logfile
      )
      Process.detach(pid)
    end

  end
end

我将WorkerJobs::SpawnTestJob.perform_async(1) 的工作排入队列,如果我跟踪test_1.log,我可以看到我的计数器正在运行。但是,当我向 sidekiq 发送 kill -15 时,计数器停止并且脚本 pid 消失。

【问题讨论】:

  • 我建议按照this answer 的流程图来确定在 Ruby 中触发和忘记子进程的最合适方法。
  • 嘿@anothermh,非常棒的图表。谢谢分享。我正在根据它生成进程,但它不起作用。

标签: ruby-on-rails ruby sidekiq


【解决方案1】:

经过数小时的调试,我最终发现是 systemd 导致了这种情况。在 sidekiq 内部启动的进程得到了 sidekiq cgroup,每当你杀死一个进程时,默认的 killmodecontrol-group

deployer@srv-14:~$ ps -efj | grep test.sh
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
deployer 16679  8455 16678  8455  0 12:59 pts/0    00:00:00 grep --color=auto test.sh
deployer 24904 30861 24904 30861  0 12:52 ?        00:00:00 sh -c cd /home/deployer &&           ./test.sh
deployer 24906 24904 24904 30861  0 12:52 ?        00:00:00 /bin/bash ./test.sh

deployer  6382     1  6382  6382 38 12:53 ?        00:02:14 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer  7787     1  7787  7787 30 12:46 ?        00:04:07 sidekiq 4.2.10 my_proj [6 of 8 busy]
deployer 13680     1 13680 13680 29 12:49 ?        00:03:08 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer 14372     1 14372 14372 38 12:49 ?        00:03:48 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer 16719  8455 16718  8455  0 12:59 pts/0    00:00:00 grep --color=auto sidekiq
deployer 17678     1 17678 17678 38 12:50 ?        00:03:22 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer 18023     1 18023 18023 32 12:50 ?        00:02:49 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer 18349     1 18349 18349 34 12:43 ?        00:05:32 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer 18909     1 18909 18909 34 12:51 ?        00:02:53 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer 22956     1 22956 22956 39 12:01 ?        00:22:42 sidekiq 4.2.10 my_proj [8 of 8 busy]
deployer 30861     1 30861 30861 46 12:00 ?        00:27:23 sidekiq 4.2.10 my_proj [8 of 8 busy]

cat /proc/24904/cgroup
11:perf_event:/
10:blkio:/
9:pids:/system.slice
8:devices:/system.slice/system-my_proj\x2dsidekiq.slice
7:cpuset:/
6:freezer:/
5:memory:/
4:cpu,cpuacct:/
3:net_cls,net_prio:/
2:hugetlb:/
1:name=systemd:/system.slice/system-my_proj\x2dsidekiq.slice/my_proj-sidekiq@9.service

我通过指示我的 sidekiq 服务 KillModeprocess 解决了这个问题

参考资料:

【讨论】:

  • 这是非常好的信息,感谢您跟踪和跟进。
  • 谢谢@MikePerham。很难找到它,因为我对 systemd 的经验有限,而且在新的 init 系统上运行 sidekiq 的资源并不多。我希望这个答案能帮助其他人,或者至少让他们更彻底地阅读 systemd 文档。
猜你喜欢
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
相关资源
最近更新 更多