タイムアウト
処理や応答を待つ時間に上限を設け、その時間を超えたら待機の打切りなどを行う仕組み。処理が入れ子になる場合は、内側の終了や後始末を外側が待てるよう、通常は内側を短く設定する。
イマシルちゃんの解説
お弁当を受け取る約束の時間があるとするよ。
お店の人は、その前に調理を終えて、包んで渡す時間も残さないといけないよね。
材料を待つだけで約束の時刻を過ぎてしまっては困るんだ。
途中であきらめる時刻も、全体の約束から逆算して決めるんだよ。
より深い解説
待ち続けると何が起きるか
返事が来ない処理を無制限に待つと、接続、メモリ、スレッドなどの資源が占有される。同じ状況が増えると、新しい要求も処理できなくなる。タイムアウトは待機に上限を設け、障害の影響を限定するために使う。
| 対象 | 待つもの |
|---|---|
| 接続 | 通信相手との接続確立 |
| 読取り | 相手から届くデータ |
| 要求全体 | 処理開始から応答完了まで |
| 業務処理 | 一連の操作の終了 |
読取りの待機時間と、要求全体に許される時間は同じではない。少しずつデータが届くと読取り用のタイマーが更新され、全体では長時間かかる実装もあるため、設定の起点と終点を確認する。
入れ子の処理の時間配分
WebサーバがAPサーバへ依頼し、APサーバがDB処理を呼び出す構成を考える。外側は、内側の処理に加えて、通信、応答の整形、失敗時の後始末を待つ必要がある。
| 待機・処理の範囲 | 独自の設定例 |
|---|---|
| DBを含む一まとまりの処理 | 4秒 |
| APの処理全体 | 6秒 |
| WebサーバがAPの返事を待つ範囲 | 8秒 |
この例では、内側が期限に達してからAP側に2秒、AP側が期限に達してからWeb側に2秒の余地を設けている。ただし、それぞれの開始時刻は同時とは限らない。実際には呼出し前の経過時間も含め、全体の締切までの残り時間を各処理へ割り当てる。
外側が先に諦めると、返す相手がいないのに内側が処理を続ける場合がある。そのため、入れ子の構成では通常内側を短くし、中止の通知が伝わるように設計する。
トランザクションタイムアウト
トランザクションは、複数の更新などを一つの処理単位として扱うものである。成功時はコミットして確定し、失敗時はロールバックして変更を取り消す。たとえば残高の減算と加算をひとまとまりにし、片方だけが確定しないようにする。
トランザクションタイムアウトは、この単位が長時間資源を占有しないように設ける期限である。期限に達したあとの取消し処理にも時間が必要なため、呼出し側に後始末の余裕を残す。
打切りと再試行の注意点
待機を打ち切ったことだけでは、相手側の処理が失敗したとは断定できない。更新は完了したが応答だけ失われた可能性もある。
| 再試行時の対策 | 目的 |
|---|---|
| 要求IDによる重複検出 | 二重の課金や注文を防ぐ |
| 冪等性の確保 | 同じ操作を繰り返しても結果を重複させない |
| 回数の制限と指数バックオフ | 障害中の相手に要求を集中させない |
短すぎる設定は正常な処理まで打ち切り、長すぎる設定は復旧を遅らせる。通常時の応答時間の分布、利用者が待てる時間、再試行を含む全体の時間から決める。