Ollama

ローカルAI自動化とサーバー検出、並行させる実戦検証の極意

Ichinose Taito — MBTI × 心理学 × AI

心理学で、
人間関係を
ちょっとラクにする。

MBTIとアドラー心理学を軸に、
自分と他者を理解するヒントを発信しています。

記事を読む ›
ちのくん
ちのくん
— こんな活動をしています —
ローカルAI自動化とサーバー検出、並行させる実戦検証の極意

ローカルAI自動化とサーバー検出、並行させる実戦検証の極意

Ollama走らせながらlaunchd監視?——それは一見シンプルに見える。でも実際やったら、ポート競合、デーモン起動タイミング、プロセス生存判定がゴチャゴチャになって、朝まで原因追いする羽目になった。その記録。

並行実行で何が壊れたか

博士号持つくらい綿密に計画したpythonパイプラインがある。Ollama(localhost:11434)でローカル推論、その傍ら定期的にサーバーの「生きてるか死んでるか」を検出する仕組みだ。

実装当初、単純な並行実行構想で試した——生成タスクをスレッド1、サーバー検出を別スレッドで並走。

[コード略 — 詳細は元記事参照]

ここまでは「動く」。だが、Ollamaプロセスが突然死ぬと、検出スレッドは気付く。でも「いつ復帰するか」の信号がない。launchd側は知らん顔。手動でkillして再起動。——毎回ロスが出る。

launchd の苦境

macOS側でOllamaをlaunchd経由で自動起動させていたんだが、デーモンとしての動作と、ユーザーランドでの検出が非同期で齟齬が起きた。

例えば、こういう設定:

[コード略 — 詳細は元記事参照]

ここで「死んだら自動復帰」を期待したんだが、実際はそうならない。KeepAlive設定がないと、Ollamaがクラッシュしても放置。

[コード略 — 詳細は元記事参照]

これを足せば「終了コード0でも自動再起動」。だが無限ループになる危険も。試行錯誤の結果、正しいのはこう:

[コード略 — 詳細は元記事参照]

「クラッシュしたときだけ」再起動。Graceful shutdown(コード0)では自動復帰しない。

ポート競合の沼

朝7時、Ollama起動。その30秒後、sanity checkスクリプトが「11434ポート、応答ナシ」と判定。えっ?——ログ見たら、Ollamaは起動してるのにバインドしてない状態だった。

原因:前回のシャットダウンで、ポート11434が TIME_WAIT 状態に残ってた。再起動時にバインドしようとしたが失敗。lsof -i :11434 で確認すると、古いプロセスが幽霊化してた。

解決には、launchd plist に SO_REUSEADDR を強制するのではなく、単純に「起動前に古いポートをクリア」するヘルパースクリプトを挟んだ:

[コード略 — 詳細は元記事参照]

起動スクリプトの最初に入れるだけ。これで「前回の残りカス」は消える。

サーバー検出の「正しい実装」

並行実行する検出側も改善した。単なるHTTPリクエストではなく、「プロセスが生きてるか」を複数方法で確認:

[コード略 — 詳細は元記事参照]

この「複数方法の同時確認」が大事。HTTPだけでは、ポートはバインドしてるけど実際に処理できてない状態を見落とす。プロセスは生きてるけどHTTP応答がない——という中途半端な故障も捕捉できる。

並行実行の「正しい頻度」

最後に気付いたのが、検出間隔の設定。5秒ごと?10秒ごと?——実際の負荷テストで、CPUがムダに上がることに気付いた。

Ollamaが推論中だと、頻繁な外部HTTPリクエストが邪魔になる。でも間隔広すぎると、障害検出が遅れる。実測値では「12秒間隔」が落としどころ:

[コード略 — 詳細は元記事参照]

単一の失敗では反応せず、3回連続で初めて「ダウン」と判定。これでflaky networkからの誤検出もなくなった。

次回やること

systemd(Linux)版も同じロジックで検証する。また、検出ログを構造化JSON形式でタイムシリーズに記録して、「何時何分にどんな理由で落ちたか」の履歴を取っておきたい。並行実行の監視品質をもっと上げるために。