【问题标题】:python supervisord program dependencypython supervisord 程序依赖
【发布时间】:2013-06-30 21:20:37
【问题描述】:

我的 supervisord.conf 中有 [program:A][program:B]

B 依赖A,意思是:

A 应该在B 之前开始。

主管如何确保这一点?

【问题讨论】:

标签: python supervisord


【解决方案1】:

supervisord 不直接支持依赖。您的选择是:

  • 使用优先级。将Apriority设置为较低的值,它将在B之前启动,在B之后关闭。 priority 的默认值为 999

    如果您也将这两个程序归为一组,那么您可以同时启动和停止它们,并通过优先级来调节它们的启动和停止顺序。

  • A写一个event listener来监听PROCESS_STATESTARTING-to-RUNNING转换和STOPPING事件,然后指示supervisord开始和停止B对那些事件。有A 自动启动,但禁用B 的自动启动,以便事件处理程序控制它。

【讨论】:

  • 我的理解是,上面的“优先级”方法很可能无法按预期工作。 Supervisord 确实会按顺序启动进程,但是例如it will not wait for process A to be fully started before commencing to start process B(即 supervisord 将忽略 startsecs 参数)。相反,它会在 A 之后立即启动 B,这在很多情况下不会(足够)你想要的。这种行为was already reported in 2012 but still isn't fixed as of 2014.
  • @miguno:那么您的选择是使用事件监听器。
  • @Cheche:优先级工作正常,但如果您希望优先级顺序还包括等待,直到更高优先级的程序达到运行状态,那么这种期望将会失望。请注意,Michael 6 年前就已经链接到了同样的问题
  • @MartijnPieters 有趣...没有注意到这一点。那么优先级仅仅是启动延迟的问题吗?
  • @Cheche:是的,没有隐含的直接依赖关系。
【解决方案2】:

如果您想走捷径,跳过阅读有关 event listeners 的文档并跳过修改程序以便它们理解事件,那么:

除了直接启动程序B(取决于A)之外,您还可以启动一个Bash 脚本,该脚本在A 启动之前一直处于休眠状态,然后再启动B。例如,如果您有一个 PostgreSQL 数据库和一个不应在 PostgreSQL 之前启动的服务器:

[program:server]
autorestart=true
command=/.../start-server.sh

[program:postgres]
user=postgres
autorestart=true
command=/usr/lib/postgresql/9.3/bin/postgres ...

然后在start-server.sh

#!/bin/bash

# Wait until PostgreSQL started and listens on port 5432.
while [ -z "`netstat -tln | grep 5432`" ]; do
  echo 'Waiting for PostgreSQL to start ...'
  sleep 1
done
echo 'PostgreSQL started.'

# Start server.
echo 'Starting server...'
/.../really-start-the-server

【讨论】:

    【解决方案3】:

    一种解决方案是使用supervisorctl:将程序B的autostart设置为false,并在A启动的程序中写入supervisorctl start B

    例子:

    supervisor.cfg:

    [supervisord]
    nodaemon=false
    pidfile=/tmp/supervisor.pid
    logfile=/logs/supervisor.log
    
    [unix_http_server]
    file=/var/run/supervisor.sock
    
    [rpcinterface:supervisor]
    supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
    
    [supervisorctl]
    serverurl=unix:///var/run/supervisor.sock
    
    [program:A]
    command=do_a
    
    [program:B]
    command=do_b
    autostart=false
    

    do_a 程序包含:

    #!/bin/bash
    #do things
    supervisorctl start B 
    

    TBH 这是@drrzmr 建议的解决方案,但我当时不明白。

    【讨论】:

    • 解决方法的问题是它需要autorestart=false。对某些应用程序很好,但对其他一些应用程序来说不是很好,例如一个数据库。
    【解决方案4】:

    this 对我来说是一个很好的解决方案!

    我使用的解决方法是将autostart=false 设置为 进程,然后使用autostart=trueautorestart=false(单发)。引导程序可以是 shell 脚本 为每个进程调用supervisorctl startsupervisorctl start 将阻塞直到进程成功启动。

    【讨论】:

    • 似乎这很容易成为 supervisor.conf 中的一个选项。
    猜你喜欢
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多