LASSIC Media らしくメディア
graceful shutdownとは|処理を取りこぼさず止める
クラウドでシステムを動かしていると、サーバーやコンテナが入れ替わる場面は日常的に起こります。新しい版へのデプロイ、負荷に応じたスケールの増減、コスト削減のためのスポットインスタンスの回収——いずれも、動いているプロセスが止められ、別のものへと置き換わる場面です。このとき、いきなりプロセスを打ち切ってしまうと、処理の途中だったリクエストが切れ、利用者にエラーが返ったり、データが中途半端な状態で残ったりします。
そこで欠かせないのが、graceful shutdown(正常終了)です。終了の合図を受け取ってから、処理中の依頼を捌ききり、後始末をしてから静かに止まる——この止め方を設計しておくことで、入れ替えのたびに生じる取りこぼしを防げます。本記事では、クラウドでシステムを運用する情報システム部門や開発担当者に向けて、graceful shutdownとは何か、近い言葉との違い、そして実装や外注の勘所を整理します。
目次
graceful shutdownとは——縮退運転・レジリエンス設計との違い
graceful shutdown(正常終了)とは、プロセスが終了の合図を受け取ったあと、すぐには止まらず、処理中の依頼を捌ききり、接続などの後始末をしてから静かに停止する止め方を指します。日本語では「正常終了」と呼ばれることもあります。乱暴に打ち切るのではなく、区切りをつけてから終わる点が特徴です。名前や文脈が似ていて混同されやすい2つの考え方と並べると、役割の違いがはっきりします。
縮退運転(graceful degradation)は、一部に不具合が出ても、機能を絞ってサービスを動かし続ける考え方です。止めるのではなく、動かし続けるための工夫を指します。またレジリエンス設計は、外部の障害に耐えるための仕組みで、応答が返らない相手への呼び出しを一時的に遮断したり、再試行したりして、全体が巻き込まれないようにするものです。これらに対してgraceful shutdownは、まさに「止めるとき」に、処理を取りこぼさず終える部分を受け持ちます。
機能を落として動かし続ける取り組みでも、障害に耐える取り組みでもなく、止める瞬間に取りこぼしを防ぐ——ここに違いがあります。名前の似た縮退運転との取り違えは、狙った設計を妨げるもとです。自社が整えたいのが、動かし続ける工夫なのか、障害への耐性なのか、それとも止め方なのかを見極めておくと、取り組みの範囲を絞りやすくなります。
この記事のポイント
- graceful shutdown(正常終了)は、動かし続ける縮退運転や障害に耐えるレジリエンス設計とは別に、止めるときに処理を取りこぼさない部分を担います。
- いきなり打ち切ると、処理中の依頼が切れて利用者にエラーが返ったり、データが中途半端な状態で残ったりします。
- 終了の合図を受けて新規受付を止め、処理中を捌き、後始末をしてから終わる流れを、猶予時間の中で設計することが要点です。
なぜ「いきなり止める」と問題が起きるのか
プロセスを止める合図には、大きく二段階があります。一つは「そろそろ終わってください」という穏やかな合図(SIGTERM)で、もう一つは「今すぐ止めます」という強制的な合図(SIGKILL)です。何も設計していないと、穏やかな合図を受けても即座に終わってしまい、処理中の依頼が道半ばで切れてしまいます。
この取りこぼしは、いくつかの形で表面化します。利用者から見れば、送信したはずの操作がエラーになったり、応答が返ってこなかったりします。データの面では、複数の更新のうち一部だけが済んだ中途半端な状態が残り、あとから整合を取り直す手間が生じるのも難点です。外部サービスとのやり取りの途中であれば、二重に処理されるといった問題にもつながります。とりわけ、入れ替えが頻繁なクラウドでは、こうした打ち切りが日常的に起こり得ます。だからこそ、止める合図を受けたら、区切りをつけてから終わる設計が欠かせないのです。取りこぼしを前提に、猶予の時間を設けて捌ききる——その一手間が、利用者の信頼とデータの整合を守ります。
graceful shutdownでやること
graceful shutdownは、ただ終了処理を書けばよいというものではなく、順序が大切です。おおまかには次のような流れを、猶予時間の中で組み立てます。自社の仕組みでどこまで実装できているかと照らし合わせてみてください。
まず、終了の合図(SIGTERM)を受け取り、これから止まる準備に入ります。次に、新しい依頼の受付を止めます。負荷を振り分けるロードバランサから自分を外し、新規のリクエストが回ってこないようにする工程です。そのうえで、すでに処理中の依頼を最後まで応答しきります(ドレインと呼びます)。続いて、データベースやメッセージキューとの接続を、中途半端に切らずにきちんと閉じる工程です。ここまで済ませてから、プロセスを終了します。注意したいのは、猶予時間には限りがあることです。決められた時間内に終わらないと、強制的な合図(SIGKILL)で打ち切られてしまうため、処理が長引く場合の対処もあわせて考えておきます。この一連の流れを図にすると次のとおりです。
つまずきやすい難所
graceful shutdownを実装するうえで、あらかじめ想定しておきたい難所がいくつかあります。着手前に押さえておくと、いざ止めるときの取りこぼしを避けやすくなります。
一つ目は、猶予時間と強制終了の兼ね合いです。捌ききるには時間が要りますが、長く待ちすぎると入れ替えが進みません。処理にかかる時間を見て、猶予をどれくらいに設定するかを決める必要があります。二つ目は、受付を止める順序です。ロードバランサから外す前にプロセスを止め始めると、その間に届いた新規の依頼が行き場を失います。外部への通知と内部の停止の順序を、取り違えないようにします。三つ目は、長時間かかる処理の扱いです。数十秒で終わらない処理は、猶予時間内に収まりません。途中で中断しても再開できる作りにするか、別の仕組みに切り出すかの判断が要ります。四つ目は、二重処理への備えです。途中で切れた依頼を後で再び実行する場合に備え、同じ処理を二度行っても結果が変わらない作り(冪等性)にしておくと、取りこぼしの後始末が楽になります。
どんな場面で重要になるか
graceful shutdownは、プロセスの入れ替えが起こる場面で役立ちます。とりわけ効果がはっきり表れるのは、入れ替えの多い環境です。代表的な場面を整理しました。
| 場面 | 何が起こるか | 止め方が甘いと |
|---|---|---|
| デプロイ(ローリング更新) | 古い版を順に新しい版へ入れ替える | 更新のたびに一部の依頼が切れる |
| オートスケールの縮小 | 負荷が下がり台数を減らす | 減らした瞬間に処理が打ち切られる |
| スポットインスタンスの回収 | 短い予告のあと強制的に停止される | 予告時間を活かせず取りこぼす |
とりわけ、コンテナを頻繁に入れ替えるKubernetesのバージョンアップ運用のような場面では、ノードを更新するたびに動いているコンテナが退避されます。このとき、それぞれのコンテナがgraceful shutdownに対応していないと、更新のたびに小さな取りこぼしが積み重なる一方です。入れ替えが前提のクラウドでは、止め方の設計が運用の安定に直結します。
外注時に確認しておきたい点
graceful shutdownの実装を外部に委託する場合は、次の点を事前にすり合わせておくと、認識のずれを防ぎやすくなります。まず、対象とするアプリと、動かしている基盤です。どんな仕組みの上で動き、どのように入れ替わるのかによって、必要な作り込みが変わります。次に、どこまでの依頼を取りこぼさず守りたいか。すべてを完璧に捌ききるのか、一部は割り切るのかで、猶予時間や実装の重さが変わってきます。
さらに、処理にかかる時間の実態と、猶予時間の設定、長時間処理の扱い、そして二重処理を防ぐ作り(冪等性)をどこまで求めるかも、あらかじめ整理しておきたいところです。graceful shutdownは、一度実装して終わりではなく、処理の内容が変われば見直しが要ります。実装だけを頼むのか、動作の確認や見直しまで含めて依頼するのかを明確にしておくと、任せたあとのつまずきを抑えやすくなります。
まとめ:graceful shutdownで押さえる3つの視点
graceful shutdown(正常終了)は、機能を落として動かし続ける縮退運転や、障害に耐えるレジリエンス設計とは役割の異なる、「止めるときに処理を取りこぼさない」設計です。検討するうえで押さえたい視点は3つに整理できます。第一に、縮退運転・レジリエンス設計・graceful shutdownを切り分け、名前の似た縮退運転と取り違えないこと。第二に、いきなり打ち切ると取りこぼしが生じると踏まえ、終了の合図を受けて新規受付を止め、処理中を捌き、後始末をしてから終わる流れを組むこと。第三に、猶予時間と強制終了の兼ね合いを見て、長時間処理や二重処理への備えまで含めて設計することです。この3点を踏まえておけば、「デプロイやスケール調整のたびに、原因の分からないエラーが少し出る」という事態を避けやすくなります。自社だけで作り込むのが難しいと感じたら、基盤に合わせた実装の設計から外部の手を借りるのも一つの選択肢です。
よくある質問
graceful shutdownと縮退運転は何が違うのですか。
縮退運転(graceful degradation)は、一部に不具合が出ても機能を絞ってサービスを動かし続ける考え方です。graceful shutdown(正常終了)は、プロセスを止めるときに処理を取りこぼさず終える止め方を指します。動かし続ける取り組みと、止め方の取り組みという関係で、役割が分かれています。名前が似ているため、取り違えないよう注意が必要です。
SIGTERMとSIGKILLはどう違うのですか。
SIGTERMは「そろそろ終わってください」という穏やかな終了の合図で、プロセス側で後始末をする余地があります。SIGKILLは「今すぐ止めます」という強制的な合図で、プロセス側では受け止める余地がなく、その場で打ち切られる合図です。graceful shutdownは、SIGTERMを受けてから猶予時間の中で後始末を済ませ、SIGKILLに至る前に終えることを狙います。
猶予時間はどれくらいに設定すればよいですか。
処理にかかる時間の実態から決めます。多くの依頼が数秒で終わるなら短めでも足りますが、時間のかかる処理があるなら、それを捌ききれる長さが要ります。ただし長くしすぎると入れ替えが進まないため、実際の処理時間を見て、無理のない範囲で設定するのが現実的です。長時間処理は別の仕組みに切り出す判断も選択肢です。
小さなアプリでも対応は必要ですか。
入れ替えが起こる環境なら、規模を問わず役立ちます。とりわけ、デプロイやオートスケール、スポットインスタンスの回収で頻繁に入れ替わるクラウドでは、対応しておかないと取りこぼしが積み重なります。まずは、終了の合図を受けて新規受付を止め、処理中を捌いてから終わる、という最小限の流れを入れるところから始めるとよいでしょう。
外注する場合、どこまで依頼できますか。
動かしている基盤の確認といった上流から、終了処理の設計、猶予時間や冪等性の作り込み、入れ替え時の動作確認まで、範囲を分けて依頼できます。どの依頼を取りこぼさず守りたいか、処理にかかる時間の実態、長時間処理の扱いをあらかじめすり合わせておくと進めやすくなります。実装後の見直しまで含めるかも決めておくとよいでしょう。
著者:テレリモ総研編集部 鈴木 亮佑
graceful shutdownの実装のご相談はLASSICへ
元請(プライムベンダー)として、基盤の確認から終了処理の設計・猶予時間や冪等性の作り込み・動作確認まで、貴社のシステムに合わせてご提案します。まずはお気軽にご相談ください。
ご不明な点はお問い合わせフォームからもご連絡いただけます。
- *1 出典:Kubernetes公式ドキュメント「Pod Lifecycle(Termination of Pods)」(https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/)