タイムアウト設計なんて怖くない
エンタープライズなシステムでは、タイムアウト設計についてドキュメント化されていることが多いでしょう。タイムアウト設計、というと私の会社ではできる人が限られています。その理由は「難しいから」ではなく「何だか得体がしれないから」なのだと、私は思っています。そこで、どんな人でもタイムアウト設計ができるように、私なりの考えをまとめておきたいと思います。
処理に上限時間を設けるのはなぜ?
タイムアウト設計では、各ポイントに上限時間を設けます。なぜ上限時間を設けるのでしょうか?一般的な理由はこうでしょう。
- 異常な事態のため、異常に時間がかかっている処理があった場合、その処理がいつまでもシステムの資源(DB接続、HTTP接続、APサーバーのスレッド、など)を占有してしまう。この結果、正常に処理できるはずの要求が処理できず、スループットが低下する。システムの資源を速やかに解放することでこのような事態を回避するため、各ポイントで上限時間を定める。
- 上記のような異常を検知するため、各ポイントで上限時間を定める。
- エンドユーザー(PCを操作するオペレータ、スマホを操作する一般ピープル)を待たせ過ぎないようにする。
なのですが、素朴な疑問がいくつか浮かびます。
- 正常に処理できるはずの処理に資源を譲る、といっても、異常が発生しているような状況では他の処理も正常に処理できない場合が多いのではないか?
- エンドユーザーに早く応答を返したとしても、エンドユーザーはリトライしてくるだけではないのか?
- 1.については、確かにその通リですが、そうでない場合もあります。そうでない場合に、せめて正常な処理だけはうまくいくようにしたい、巻き込みたくない、というのが上限時間を設ける目的なんですね。
- 2.についても、その通リです。異常が一時的なサーバー負荷の高騰なのであれば、リトライすることでうまくいく可能性は高いでしょう。そのような場合は特に問題はありません。そうでない場合は、障害として何らかの形で検知され、SEが(死ぬような思いで)障害対応をすることで解決を目指すことになります。
極端な話、上限時間を設けなかったらどうなってしまうのでしょうか?本当に、困るのでしょうか?
- 資源が占有され続けた場合、資源が定常的に少ない状態となりますから、SLAの通リのスループットが出ず顧客に怒られるかもしれません。
- 資源を占有するような要求が次々とやってきた場合、資源はどんどん占有され、スローダウンを引き起こしてしまうでしょう。正にセキュリティ攻撃、という感じですね。一方、何らかの不具合が原因なのであれば、最悪の場合、上限時間を設定したととしても、次々と上限を超過してエラーが多発するでしょうから、どのみち大騒ぎということになりますが・・・。まあ、スローダウンしてシステム停止、よりはマシでしょう。不具合が発生したとしても、上限時間を設けるのはベターなのです。
- 処理量が少ないうちはエンドユーザーからの苦情なく処理できるかのように見えたとしても、もっと量が増えれば破綻する可能性があります。早いうちに「何だか遅いな」と気付ければ早めの対処ができるでしょう。これができなければ、処理量が増えてきた場合にエンドユーザーが「遅いな、使いにくいな」と感じてしまい、人気がなくなってしまうかもしれません。
少しそれましたが、先に進みましょう。
上限時間を設けるのがどうやら良さそうなのですが、闇雲に上限時間を設定すればOKというものではありません。
タイムアウトを設計する、とは?
更新系の処理では上限時間が不適切に設定されていると、色々な「不整合」が発生し得ます。例えば、以下のようなシステム構成だとしましょう。
このような不整合が発生しないように、システムの上限時間は適切に設定する必要があります。
ここに「設計」という概念が入ってくるわけです。
そもそも入り口の上限時間をどうするか、というのも「設計」なのですが。
ただし、このような不整合を完全に防ぐことはできません。可能な限り不整合を防ぎましょう、というのがタイムアウト設計なのです。