自動化処理が 2 回走っていた——二重起動問題の根本原因と根絶パターン
2026-05-05
🎯 結論
今日、社内の自動化ルーティン群に二重起動が発生していることを確認し、根本修正を完了した。原因はシンプルだ——「個別ルーティンが持つスケジュール設定」と「一括で呼び出す外部トリガー」が同時に有効になっていた。修正は一行——個別ルーティン側のスケジュール設定を削除し、起動の責任を一か所に集約した。あわせて、外部画像サービスへのポーリングが過剰に短いという別インシデントも同日中に対処した。
◾️ 背景:二重起動はいつ起きるか
無人実行の処理が増えると、ある時点で「起動タイミングの管理」が複雑になる。当社の場合、各ルーティンはそれぞれ独立した定義ファイルを持ち、そこにスケジュール設定を内包していた。当初はこれで問題がなかった。
問題が起きたのは、ルーティンの数が一定を超えた後に「複数ルーティンを一括で呼び出す仕組み」を追加したときだ。一括起動は既存のルーティンをまとめて呼び出す——その際、個別ルーティン自身もスケジュール設定を持ったままだったため、同じ処理が 2 経路から同時に起動する状態が生まれた。
二重起動は単純に処理が 2 回走るだけでなく、ファイル書き込みの競合・外部 API 消費量の倍増・ログの解読困難という三重の問題を引き起こす。今回、表面化したシグナルは「外部画像サービスへのポーリングが詰まっている」という症状だった。原因を辿ったところ、同じ処理が 2 本並走していたことが判明した。
◾️ Phase 0 緊急パッチ:ポーリング過多の応急処置
まず先に対処したのが、外部画像サービスへのポーリング間隔だ。当時の設定は「5 秒おきに最大 4 分間ポーリング」——つまり 1 処理あたり最大 48 回の問い合わせを投げていた。これが 2 本並走すると、96 回になる。サービス側から制限のシグナルが出たため、緊急パッチとして「15 秒おき・最大 90 秒」に変更した。1 処理あたり最大 6 回に抑え、並列が重なっても制限に引っかかりにくい余白を確保した。
これは対症療法だ。根本にある二重起動が解消されない限り、ポーリング間隔を調整しても問題は再燃する。緊急パッチを打った直後に「根本原因の記録」を残し、翌朝ではなくその日のうちに構造修正に着手した。
◾️ Phase 1a / 1b / 1c:構造からの根絶
緊急パッチの後、三段階で構造を修正した。
Phase 1a では、個別ルーティンのスケジュール設定をすべて削除した。起動は一括起動経路に一本化し、個別ルーティンは「呼ばれたら動く」設計に変えた。この変更で、二重起動の根本原因を取り除いた。
Phase 1b では、日次記事公開ルーティンに「保存・リモート反映」ステップが不完全だったことが判明し補完した。単体では正常動作していたが、一括起動経路で動かすと最終ステップが省略されるケースがあった。各ルーティンが「一括起動経路から動いたときも完結する」設計になっているかを個別に検証する工程の必要性を確認した。
Phase 1c では、6 本のルーティンについて実行手順書(ランブック)を独立したファイルとして切り出した。これまでは定義ファイルの中に実行詳細が埋め込まれていたため、ファイルが長大になり、問題発生時の原因特定が遅れていた。ランブックを分離することで「何を実行するか(定義)」と「どう実行するか(手順書)」が分かれ、問題箇所の特定コストが下がった。
◾️ 教訓と SOP 化
今回の対応から引き出した原則を記録する。
原則 1: 起動の責任は一か所に集約する
処理に「自身のスケジュール設定」と「外部トリガー」の両方を持たせると、将来必ず二重起動が発生する。個別の処理は「呼ばれたら動く」設計を維持し、起動タイミングの判断は専用の起動管理層だけが行う。
原則 2: 緊急パッチを打った直後に根本原因を記録する
対症療法は現象を抑えるが、根本原因が残っている間は潜伏インシデントになる。「今どこに根本原因があり、いつ根本修正するか」をパッチ直後に明文化することで、作業負債が見えない状態で積み上がるのを防ぐ。
原則 3: ランブック分離は構造の可読性への先行投資だ
定義ファイルに実行詳細を詰め込むと、処理数が増えるにつれてファイルが長大化し、問題箇所の特定コストが線形に上がる。ルーティンが 10 本を超えた時点でランブック分離を積極的に行う。
Phase 1a / 1b / 1c の修正で二重起動問題は根絶した。次の課題は二重起動が起きていたことを早期に検知できなかったという監視の問題だ。今回、気づいたのは「ポーリング詰まり」という別の症状が表面化してからだった。異常な実行回数の増加を自動で検知する仕組みをどう設計するか——「処理が安定稼働している」状態の次に取り組む課題として、ここに記録しておく。