Sauce::Service: sauce_serviced

BlueOnyx: Sauce::Service

BlueOnyx では、サービス関連のトランザクションはすべて Sauce::Service Perl モジュールを通じて処理されます。これにより、サービスが有効か、実行中かを確認し、有効/無効化したり、再起動や停止などの実行状態を変更できます。

これは通常かなりうまく機能してきましたし、Sauce::Service も長年にわたって何度か改良されてきました。それでも 1 つの問題が残っていました。

PHP-FPM を統合して以降、Apache (と Nginx) の再起動は通常 PHP-FPM の再起動も伴います。これにより大量のサービス再起動要求が発生し、しかもかなり重複することが多くありました。

これは Sauce::Service Perl モジュールの再設計によって解決され、その対応 YUM 更新が BlueOnyx 5209R、5210R、5211R 向けに公開されました。

Sauce::Service の一般機能

Sauce::Service は常に 3 つの部分から構成されており、これは今も変わっていません。

- Sauce::Service

サービス処理のトップレベル関数

- Sauce::Service::Client

サービス関連トランザクションを Sauce::Service::Daemon に送る役割

- Sauce::Service::Daemon

キューされた systemctl 呼び出しを処理する役割

通常の CCE ハンドラやコンストラクタでは、サービス再起動を 2 通りの方法で行えます。

Sauce::Service::service_run_init('service-name', 'restart', 'nobg');</code><br><code>Sauce::Service::service_run_init('service-name', 'restart');

最初のもの ('nobg' パラメータ付き) は、リクエストをバックグラウンドキューへ入れず、即時実行して再起動が終わるまで待つよう指示します。

2 番目のもの ('nobg' なし) は、リクエストをキューへ入れてバッチ処理させる指示です。

このバッチ処理は Sauce::Service::Client が短命な Sauce::Service::Daemon インスタンスを起動し、それがキュー済みリクエストを処理し、もう処理対象がなければ停止するという方式でした。

この方式は、元の Cobalt 開発者にとっては良いアイデアでしたが欠点もありました。Sauce::Service::Client は Unix ソケット経由で Sauce::Service::Daemon と通信していましたが、Unix ソケットを使うデーモンはソケット待受かトランザクション処理のどちらかしか同時にできません。さらに ALARM ハンドラや SigChld 呼び出しでキュー処理を起動していたため、挙動上の癖もありました。その結果、実行時の厄介な問題や奇妙な振る舞いが発生していました。

25 年以上前の発想としては優れていましたが、現代には最適とは言えません。

近代化された Sauce::Service の機能

Sauce::Service 自体はほぼ変わっていません。

Sauce::Service::Client はもはや Sauce::Service::Daemon を起動しません。現在の仕事は /usr/sausalito/services/ にフラットファイル DB を書き込むことだけです。そこには対象サービス名、実行内容 (restart、stop など)、タイムスタンプが記録されます。特定サービスのエントリが既に存在する場合は更新され、新しいタイムスタンプが付き、状況に応じて命令内容 (stop、restart、reload) が昇格または降格されます。

Sauce::Service::Daemon は現在、バックグラウンドで常駐する完全なデーモンです。"systemctl restart sauce_serviced.service" で起動され、デフォルトで有効かつ動作中です。失敗しても、systemd は cced.init と同様に自動再起動します。

● sauce_serviced.service - Sauce Service Daemon
     Loaded: loaded (/usr/lib/systemd/system/sauce_serviced.service; enabled; preset: disabled)
    Drop-In: /run/systemd/system/service.d
             └─zzz-lxc-service.conf
     Active: active (running) since Sun 2026-03-08 00:01:04 -05; 2s ago
    Process: 2187688 ExecStart=/usr/sausalito/perl/Sauce/Service/sauce_serviced.pl (code=exited, status=0/SUCCESS)
   Main PID: 2187756 (sauce_serviced)
      Tasks: 1 (limit: 306113)
     Memory: 5.5M (peak: 7.3M)
        CPU: 77ms
     CGroup: /system.slice/sauce_serviced.service
             └─2187756 sauce_serviced

Mar 08 00:01:00 5211r.smd.net systemd[1]: Starting Sauce Service Daemon...
Mar 08 00:01:04 5211r.smd.net sauce_serviced[2187756]: Daemon.pm: sauce_serviced[2187756] Ready to accept requests
Mar 08 00:01:04 5211r.smd.net systemd[1]: Started Sauce Service Daemon.

Sauce::Service::Daemon の唯一の仕事は、/usr/sausalito/services/ を 15 秒ごとに確認し、トランザクションファイルがあればタイムスタンプを調べることです。ファイルが 10 秒以上前のものであれば処理され、キュー済み systemctl トランザクションが実行されます。"stop" 要求はほぼ即時に処理され、それ以外は順番待ちになります。

つまり通常の...

Sauce::Service::service_run_init('<service>', 'restart');

... は ('nobg' が付いていない限り) すぐには実行されません。代わりに遅延が入ります。この遅延により、短時間に重複して発生する同一サービス向けの不要な再起動要求の大半を排除できます。

結果:

たとえば GUI で PHP 設定を保存すると、関連サービスの再起動まで 30 秒から 1 分かかることがあります。ただし GUI でその間待つ必要はありません。再起動は CODB への SET トランザクションが完了した後にバックグラウンドで行われるからです。保存後は比較的すぐに GUI ページが再読み込みされて結果が表示され、その裏で Sauce::Service::Daemon が処理を進めます。

主な利点は、systemd が冗長なサービス再起動の洪水にさらされなくなり、安定性が向上することです。これらの再起動がバックグラウンド処理になることで、GUI の応答性も改善されます。