web-dev-qa-db-ja.com

スーパーバイザーをCRONとして使用

supervisor を設定して、X秒ごとにコマンドを実行する方法はありますか(CRONなど)?

EventlistenerとTICK_ eventの例を見る

[eventlistener:memmon]
command=memmon -a 200MB -m [email protected]
events=TICK_60

ただし、コマンドは1回だけ実行されます。

30
barbushin

問題

Memmonの例で見ているように、supervisordは各イベントでmemmon -a 200MB -m [email protected]を実行していません。むしろ、このイベントリスナーを1回(またはプールを構成している場合は数回)起動してから、既存のプロセスの標準入力を介して各新しいイベントを送信します。

溶液

したがって、イベントでトリガーする機能の追加タイプごとに、スーパーバイザー互換のイベントリスナーを検索または作成する必要があります。

実装方法の例

構成をセットアップしてリスナーを作成する

supervisord.cfgイベントセクションを書く

[eventlistener:passthru]
command=/tmp/simple.py /bin/date -u +"%%s %%S:%%H:%%d:%%m"
events=TICK_60

(注- configParserの% のエスケープ)

simple.pyイベントリスナーを書く

docsのサンプルリスナー に変更を加えて、このsimple.pyリスナーを作成します。これにより、最初の引数を残りの引数とともに実行します。

#! /usr/bin/python
import sys
import subprocess

def write_stdout(s):
    sys.stdout.write(s)
    sys.stdout.flush()

def write_stderr(s):
    sys.stderr.write(s)
    sys.stderr.flush()

def main(args):
    while 1:
        write_stdout('READY\n') # transition from ACKNOWLEDGED to READY
        line = sys.stdin.readline()  # read header line from stdin
        write_stderr(line) # print it out to stderr
        headers = dict([ x.split(':') for x in line.split() ])
        data = sys.stdin.read(int(headers['len'])) # read the event payload
        res = subprocess.call(args, stdout=sys.stderr); # don't mess with real stdout
        write_stderr(data)
        write_stdout('RESULT 2\nOK') # transition from READY to ACKNOWLEDGED

if __name__ == '__main__':
    main(sys.argv[1:])
    import sys

スーパーバイザ構成が機能することを確認してください

$ supervisorctl [-c cfg]
supervisor> status
passthru                         RUNNING   pid 4471, uptime 0:00:32
supervisor> tail passthru
  OKREADY
  RESULT 2
  OKREADY
  ...
supervisor> tail passthru stderr
supervisor> tail passthru stderr
  ver:3.0 server:supervisor serial:0 pool:passthru poolserial:0 eventname:TICK_60 len:15
  1451411161 01:17:29:12 <--- output
  when:1451411160ver:3.0 server:supervisor serial:1 pool:passthru poolserial:1 eventname:TICK_60 len:15
  1451411220 00:17:29:12 <--- output
  when:1451411220

現在、date -u +"%s %S:%H:%d:%m"は60秒ごとに実行されています。

目的のコマンドでのスワップ

実行可能スクリプトを作成します

/tmp/hiworld.php:

#! /usr/bin/php
<?= "hiya\n"; 

(chmod + x ...)

supervisord.cfgのリスナーの引数を変更する

[eventlistener:passthru]
command=/tmp/simple.py /tmp/hiworld.php
;stdout_logfile=/tmp/passthru 
events=TICK_60
;autorestart=true
;startsecs=0

スーパバイザおよびテストのリロード(再読み込みはこの変更を検出しないようです)

supervisor> reload
   Really restart the remote supervisord process y/N? y
   Restarted supervisord
supervisor> status
   passthru                         RUNNING   pid 6017, uptime 0:00:10
supervisor> tail passthru stderr
supervisor> status
   passthru                         RUNNING   pid 6017, uptime 0:00:21
supervisor> status
   passthru                         RUNNING   pid 6017, uptime 0:01:01
supervisor> tail passthru stderr
   ver:3.0 server:supervisor serial:316 pool:passthru poolserial:0 eventname:TICK_60 len:15
    hiya
   when:1418926740
supervisor> 

終わり

これで、目的のコマンドが60秒ごとに実行されます。これで、アクセス許可、場所、ログなどの詳細を調整するために読み取られます。

20
lossleader

なぜ車輪を発明するのですか? cronsupervisordを一緒に使用できます。

スーパーバイザーで、autostart=falseでタスクを作成します

Cronでは、* * * * * supervisorctl start <taskname>を使用して毎分タスクを開始します

12
AlexM

スーパーバイザはこれを簡単にサポートしません。

しかし、目標を達成するには、スーパバイザを使用してcronを起動するだけです(たとえば、Dockerコンテナの場合):

https://Gist.github.com/martinrusev/7015e393d46647dbad15

6
wid

Crobtabを使用して、スーパーバイザープログラムを管理およびスケジュールできます。

コマンドsupervisorctl start <program_name>を使用します

:これは、監視プログラムの単一インスタンスのみを開始します。すでに実行されていて、crontabが再度トリガーしようとすると、supervisorctl startコマンドは新しいインスタンスを開始しません。

2
Raman

Bash sleepコマンドを呼び出すことができます:

[program:mycmd]
command=bash -c 'sleep 300 && exec <your command here>'

これにより、5分ごとにコマンドが実行されます。スーパーバイザーが正しい終了コードを取得できるように、exec部分を忘れずにbashプロセスをコマンドに置き換えてください。

1
mixel