LASSIC Media らしくメディア
タイムアウト設計とは|障害の連鎖を防ぐ勘所
ある処理が、待てど暮らせど返ってこない。呼び出した相手の調子が悪いだけなのに、こちらの処理まで巻き込まれて止まり、やがてシステム全体が身動きできなくなる——。障害の現場では、こうした「待ち続けたことによる連鎖」がしばしば起こります。これを防ぐ、地味だけれど効き目のある備えが、タイムアウトの設計です。
タイムアウトとは、「ここまで待って応答がなければ、待つのをやめる」という上限を、あらかじめ決めておく仕組みです。単純に思えて、値の決め方や、リトライとの組み合わせ方を誤ると、かえって障害を広げることもあります。本記事では、システムの設計・運用にたずさわる情報システム部門の担当者に向けて、タイムアウトとは何か、近い考え方との違い、種類と勘所、そして値の決め方や外注の考え方を整理します。
目次
タイムアウトとは——リトライ・サーキットブレーカーとの違い
タイムアウトとは、ある処理の完了を待つ時間に上限を設け、それを超えたら待つのをやめて次の動きに移る仕組みを指します。外部のサービスやデータベースを呼び出したとき、相手からの応答がいつまでも返らないと、呼び出した側はその処理を抱えたまま待ち続けます。待っている処理が増えていけば、やがて手が回らなくなり、正常なはずの機能まで巻き込まれて止まってしまうのです。タイムアウトは、この「終わりのない待ち」を断ち切るための、いわば見切りをつける時間です。
混同されやすい考え方に、リトライやサーキットブレーカーがあります。リトライは、失敗した処理をもう一度試みる仕組みで、タイムアウトで見切りをつけたあとの「次の一手」にあたるものです。サーキットブレーカーは、失敗が続く相手への呼び出しを一時的に遮断する仕組みで、こちらも障害の連鎖を防ぐ狙いを持ちます。これらは、レジリエンス(障害への耐性)の設計としてまとめて語られることが多いものです。
その中でタイムアウトは、すべての起点になる備えだといえます。まず待つ時間に上限を設けてはじめて、リトライやサーキットブレーカーが意味を持つのです。上限がないまま再試行や遮断だけを組み込んでも、そもそも見切りがつかず機能しません。順番としては、まずタイムアウトを決め、その上にリトライやサーキットブレーカーを重ねていく——この土台の位置づけを押さえておくと、設計の見通しが立てやすくなります。
この記事のポイント
- タイムアウトは「終わりのない待ち」を断ち切り、障害の連鎖を防ぐための時間の上限です。
- リトライやサーキットブレーカーの土台になり、上限を決めてはじめてそれらが機能します。
- 短すぎても長すぎても弊害が出るため、実測をもとに調整し続けることが欠かせません。
なぜ必要なのか
タイムアウトが求められる背景には、システムが単独では完結しないという現実があります。いまのシステムは、外部のサービスやデータベース、他社のAPIなど、多くの相手と連携しながら動くものです。その相手のどれか一つでも応答が遅れたり止まったりすると、影響は呼び出した側へ及びます。
ここで上限がないと、何が起きるでしょうか。応答を待つ処理は、待っているあいだ、限りある資源(接続やメモリなど)を握ったままになります。待ちが積み重なると資源が尽き、本来は無関係だったはずの処理まで受け付けられなくなるのです。こうして、一つの相手の不調が、システム全体の停止へと連鎖していきます。タイムアウトは、この連鎖の入口でいったん見切りをつけ、被害が広がる前に食い止める役割を担います。相手の不調をこちらで抱え込まず、切り離して次の対処へ移る——そのための最初の一線が、タイムアウトなのです。だからこそ、外部と連携する処理には、原則として上限を設けておくことが求められます。
タイムアウトの種類と勘所
ひとくちにタイムアウトといっても、どの段階に上限を設けるかで、いくつかの種類に分かれます。全体像をつかんでおくと、どこに備えが足りていないかが見えてくるはずです。代表的なものを挙げます。
一つ目は、接続タイムアウトです。相手とつながるまでの待ち時間の上限で、相手が存在しない、あるいは混み合っている状況を早めに見切る狙いがあります。二つ目は、読み取りタイムアウトです。つながったあと、応答が返ってくるのを待つ時間の上限で、処理が遅い相手にいつまでも付き合わされるのを防ぎます。三つ目は、全体のデッドラインという考え方です。一連の処理全体に「この時刻までに終える」という締め切りを設け、途中で複数の相手を呼ぶ場合には、残り時間を後続へ引き継いでいきます。これにより、個々の上限は守れていても全体では待ちすぎる、という事態を避けられます。関係を図にすると、次のとおりです。
つまずきやすい難所
タイムアウトの設計には、あらかじめ想定しておきたい難所があります。踏まえておくと、「入れたのにかえって不安定になった」という結末を避けやすくなります。
まず、値が短すぎる場合です。処理の実態より短く設定すると、本来なら正常に終わるはずの処理まで打ち切ってしまいます。しかも、打ち切られた処理がリトライで再送されると、相手にはよけいな負荷がかかり、状況を悪化させることさえあります。次に、値が長すぎる場合です。上限が緩すぎると、不調な相手を待つ処理が積み上がり、資源を握ったまま詰まっていきます。結局、上限がないのに近い状態になり、障害が呼び出し元へ連鎖します。三つ目は、リトライとの掛け合わせの見落としです。タイムアウトの時間に再送の回数を掛けると、最悪の場合の待ち時間はふくらみます。ここを見積もらずに組み合わせると、想定よりずっと長く待つ設計になりがちです。四つ目は、設定漏れです。一部の呼び出しだけ上限がないと、そこが弱点になって全体を巻き込みます。外部と連携する箇所には、もれなく上限を設ける必要があるのです。いずれも、「入れること」ではなく「適切な値で、もれなく入れること」を意識すると避けやすくなります。
値の決め方と運用
では、タイムアウトの値はどう決めればよいのでしょうか。決まった正解はなく、経路や処理の内容によって適切な値は変わります。そのため、勘だけに頼らず、実測をもとに決めて調整していく進め方が現実的です。目安となる考え方を整理しました。
| 段階 | やること | 見るポイント |
|---|---|---|
| 初期設定 | 実際の応答時間を測る | 普段どれくらいで返るかの分布を把握 |
| 値の決定 | 通常の応答に余裕を足して決める | 短すぎ・長すぎの弊害の間で見極める |
| リトライ併用時 | 最悪の待ち時間を見積もる | 上限×再送回数が許容範囲に収まるか |
| 運用中 | 実績を見て見直す | 打ち切りの頻度・遅延の傾向の変化 |
鍵になるのは、実測に基づくことと、一度決めて終わりにしないことです。まず普段の応答時間を測り、そこに余裕を足した値から始めます。そのうえで、運用しながら打ち切りの頻度や遅延の傾向を見て、短すぎれば延ばし、長すぎれば縮めるという調整を重ねるのが基本です。システムや連携先は変わっていくため、当初は妥当だった値も、しだいに実態と合わなくなるものです。定期的に見直す前提で運用すると、タイムアウトが形だけの設定になるのを防げます。
外注時に確認しておきたい点
タイムアウトの設計や見直しを外部に委託する場合は、次の点を事前にすり合わせておくと、認識のずれを防ぎやすくなります。まず、対象とする範囲です。どの連携やどの処理に上限を設けるのか、外部と接する箇所を洗い出したうえで、抜けがないかを確認しておきたいところです。次に見ておきたいのが、リトライやサーキットブレーカーといった周辺の仕組みとの兼ね合いになります。タイムアウトはこれらの土台になるため、切り離さずにまとめて設計してもらうと、ちぐはぐな組み合わせを避けられます。
さらに、値をどう決め、どう見直すかの進め方も決めておきたい点です。実測に基づいて決めるのか、見直しは誰がいつ行うのか、打ち切りが起きたときにどう気づくのか——ここを詰めておかないと、設定した値が実態と合わなくなっても放置されがちです。あわせて、ヘルスチェックやgraceful shutdown(正常終了)など、信頼性にかかわる他の設計と足並みをそろえて依頼すると、全体として一貫した備えになります。設計だけを頼むのか、運用しながらの調整まで含めて依頼するのかを明確にしておくと、任せたあとのつまずきを抑えやすくなります。
まとめ:タイムアウト設計で押さえる3つの視点
タイムアウトは、「終わりのない待ち」を断ち切り、一つの相手の不調がシステム全体へ連鎖するのを食い止める、地味ながら重要な備えです。押さえておきたい視点は3つに整理できます。第一に、タイムアウトはリトライやサーキットブレーカーの土台であり、まず上限を決めてはじめてそれらが機能すると理解すること。第二に、接続・読み取り・全体のデッドラインといった種類を踏まえ、外部と接する箇所にもれなく上限を設けること。第三に、短すぎても長すぎても弊害が出るため、実測をもとに値を決め、運用しながら見直し続けることです。この3点を踏まえておけば、「待ち続けて共倒れ」という事態も、「打ち切りすぎて逆に不安定」という事態も、どちらも避けやすくなります。設計や調整に不安があれば、外部の手を借りるのも一つの選択肢です。
よくある質問
タイムアウトとリトライはどう違うのですか。
タイムアウトは、応答を待つ時間に上限を設け、超えたら待つのをやめる仕組みです。リトライは、失敗した処理をもう一度試みる仕組みで、タイムアウトで見切りをつけたあとの次の一手にあたります。まず上限を決めてはじめてリトライが機能するため、タイムアウトはリトライの土台にあたる関係だと捉えると分かりやすいでしょう。
タイムアウトの値はどう決めればよいですか。
決まった正解はなく、経路や処理の内容で適切な値は変わります。基本は、普段どれくらいで応答が返るかを実測し、そこに余裕を足した値から始める進め方です。運用しながら、打ち切りの頻度や遅延の傾向を見て、短すぎれば延ばし、長すぎれば縮める調整を重ねます。勘だけで決めず、実測に基づくことが大切です。
接続タイムアウトと読み取りタイムアウトは何が違うのですか。
接続タイムアウトは、相手とつながるまでの待ち時間の上限で、相手が存在しない、あるいは混み合っている状況を早めに見切るためのものです。読み取りタイムアウトは、つながったあとに応答が返るのを待つ時間の上限で、処理が遅い相手に付き合わされ続けるのを防ぎます。段階が異なるため、両方を設けておくのが基本です。
タイムアウトは短いほどよいのですか。
そうとは限りません。短すぎると、本来なら正常に終わる処理まで打ち切ってしまい、リトライで再送された分だけ相手によけいな負荷がかかることもあるのです。逆に長すぎると待ちが積み上がって詰まります。短すぎと長すぎの弊害の間で、実測を踏まえて見極めることが求められます。
外注する場合、どこまで依頼できますか。
外部と接する箇所の洗い出しから、リトライやサーキットブレーカーとの兼ね合いを踏まえた設計、実測に基づく値の決定、運用しながらの見直しまで、範囲を分けて依頼できます。ヘルスチェックやgraceful shutdownなど信頼性にかかわる他の設計と足並みをそろえると一貫した備えになるはずです。設計だけか運用まで含めるかを明確にしておくと引き継ぎやすくなります。
著者:テレリモ総研編集部 鈴木 亮佑
タイムアウト・信頼性設計のご相談はLASSICへ
元請(プライムベンダー)として、外部連携の洗い出しからリトライ等との兼ね合いを踏まえた設計・実測に基づく値の決定・運用しながらの見直しまで、貴社のシステムに合わせてご提案します。まずはお気軽にご相談ください。
ご不明な点はお問い合わせフォームからもご連絡いただけます。
- *1 参考:Google「Site Reliability Engineering(Addressing Cascading Failures)」(https://sre.google/sre-book/addressing-cascading-failures/)。具体的な設定値は各システムの実測に基づいて設計してください。