デプロイバックグラウンドワーカー

バックグラウンドワーカー

Lizard (lizard.build) のバックグラウンドワーカーは、HTTP ポートを持たないサービスです。 キューコンシューマー、更新をポーリングするボット、reconciler、ポーリングループなど。コンテナポートを 0 に設定して、たとえば lizard up --port 0 で worker mode を有効にしてください。ワーカーには PORT、readiness probe、パブリックルートが与えられないため、HTTP に応答しないことを理由に unhealthy とマークされることはありません。ジョブキューには Managed Redis と組み合わせてください。チャットボットもワーカーです。Telegram bot と Discord bot のガイドを参照してください。

worker mode で変わること

containerPort=0 の場合、プラットフォームは次のように動作します:

  • PORT injection をスキップ:ワーカーはどこにも bind しません。
  • TCP readiness probe をスキップ:誤検知の “unhealthy” ステータスは発生しません。新しい pod が起動する前に古い pod が停止します。
  • 合成された Dockerfile の EXPOSE をスキップ。
  • ロードバランサーのルート登録をスキップ:何も配信されません。(生成された *.onlizard.com ドメインがサービス上に表示される場合はありますが、応答しません。)

worker mode を有効にする

同等の方法が 3 つあります:

# New upload-source worker
lizard up --port 0
 
# Flip an existing service
lizard port 0 --service worker
 
# Via the config:apply path
lizard service set worker --set containerPort=0

worker mode は完全な切り替えです。ポート変更を反映するには再デプロイが必要です。

現在のポートを確認する

lizard port --service worker

現在のコンテナポート、またはそれが 0 の場合は worker mode を表示します。

worker mode を使うべきでない場合

起動が遅いだけの通常の HTTP サービスには worker mode を使わないでください。worker mode は到達性チェックを完全に無効化するため、「リスナーが起動しなかった」 バグを隠してしまいます。サービスがトラフィックを処理する想定なら、実際のポートを維持し、代わりに起動処理を修正してください。

キューコンシューマーを実行する

redis-workerの例 を使います。これはジョブを pending リストから processing リストへ移動し、その大文字化した結果を保存し、Redis トランザクションでジョブを確認済みにします。レプリカは 1 つのままにしてください。起動時の復旧は単一コンシューマーを前提にしています。この例は Python 3.13 と redis-py 6.4.0 を使います。

その Dockerfile を含むディレクトリから実行します:

lizard init --name queue-example
lizard add --service worker
lizard add redis
lizard secrets set REDIS_URL='${{redis.REDIS_URL}}' --service worker
lizard up --service worker --port 0

コマンドで認証が必要と表示されたら、lizard login でサインインしてください。データベースの実際の名前が redis でない場合は、その名前を使用してください。参照は引用符で囲んだままにしてください。アプリケーションをアップロードする前に設定します。

最後のデプロイイベントを確認し、その後ワーカーを確認します:

lizard port --service worker
lizard logs --service worker --json

自分のコンピューターからジョブを送信します。lizard run --service redis は、Redis アドオンの接続値(公開用の REDIS_URL を含む)を使ってローカルコマンドを実行します:

python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
lizard run --service redis -- python jobs.py enqueue first-job
lizard run --service redis -- python jobs.py result first-job

プロセスは Queue worker ready を出力し、ジョブの実行後に Processed first-job を出力します。ログの tail が空の場合は、ジョブ確認の結果で判断してください。test results に観測されたロギング制限が記録されています。結果確認コマンドは最大 30 秒待機し、{"id": "first-job", "result": "HELLO"} を表示します。プロセスが動作中であることだけでは、ジョブを消費できる証明にはなりません。

再起動を検証する

このテストサービスでは、ワーカーを再起動して別のジョブを送信します:

lizard restart --service worker
lizard run --service redis -- python jobs.py result first-job
lizard run --service redis -- python jobs.py enqueue after-restart
lizard run --service redis -- python jobs.py result after-restart

30 秒経っても after-restart の結果がない場合は、lizard ps --json でサービスが running に戻るまで待ってから、結果確認コマンドをもう一度実行してください。両方の結果は HELLO になるはずです。最初の結果は Redis に保存されるため、ワーカーを再起動しても削除されません。起動時に単一コンシューマーは未完了の processing エントリを pending リストに戻します。

このデモは jobs.py が作成した JSON ジョブのみを受け付けます。dead-letter queue、信頼できない producer 向けのバリデーション、または external side effects の exactly-once は実装していません。支払い、メール、その他の副作用には、実績のあるキューライブラリと冪等なハンドラーを使用してください。Redis の永続性とバックアップは、ワーカー再起動時の挙動とは別です。ストレージとリカバリ を参照してください。

トラブルシューティング

症状確認
サービスが見つからないプロジェクト作成後に lizard add --service worker を実行してください。
Queue worker ready がないサービススコープの REDIS_URL、addon の準備完了状態、接続エラーを確認してください。接続文字列は絶対に表示しないでください。
ワーカーが HTTP ポートを想定しているcontainerPort=0 を設定してください。実行中サービスでこれを変更するには再デプロイが必要です。
30 秒後も結果がないワーカーログを読み、ジョブ ID を確認してください。この例は自身の jobs.py からのジョブのみ受け付けます。
副作用が重複するリトライにより処理が再実行されることがあります。この例は結果をジョブ ID ごとに保存します。external effects には独自の冪等性が必要です。

関連項目

確認済みバージョン、クラウドでの結果、残っている制限については、シナリオテストの結果 を参照してください。

更新日