ゲームラグ白書 › L8 ソケットとプロトコル
TCPのRTOと指数バックオフ RTO and exponential backoff
原因ID sk-rto · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
図と実験のあるメインページでこのカードを開く →
再送がまた失敗するたびに待ち時間が2倍に延びるため、短い回線断が長い停止になります。
なぜ 回線が一瞬切れて、再送も続けて失敗 → すると 次の試行までの時間が0.3 → 0.6 → 1.2 → 2.4秒のように2倍ずつ延びる(Ping 100msの場合) → 画面では 回線が切れたのは1秒なのに、ゲームは2秒以上止まる。さらに長く切れると最終的に切断
- 症状
- フリーズ, 切断
- 要因
- パケットロス, ストール
- 誰に起きるか
- 自分だけ
- いつ
- ときどきランダムに, 移動中・マップ切り替え時
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 ゲーム開発チーム・クライアント開発
- ゲーム開発チームの対応
- サーバー:ハートビートに応答し、一定時間受信がなければ接続を先に整理(TCP_USER_TIMEOUTであきらめるまでの時間を短縮)、セッショントークンでセッションを引き継ぐ、信頼性UDP。クライアント:短い間隔でハートビートを送り、応答が途絶えたらTCPの再送を待たずにすぐ再接続。
- 数値の目安
- LinuxのRTO(再送待ち時間)は「Ping+200ms」が最小で、接続を確立するときは1秒から始まります。デフォルト設定(tcp_retries2=15)では、再送が失敗し続けても約15分後にようやく接続をあきらめます。
- グラフでは
- 途切れた後にまとめて到着 · 接続ごとのRTO・backoff、RTOの満了回数
- 確認箇所
- 止まった接続をss -tiで確認してrto(再送待ちのms)とbackoff(連続満了回数)を、サーバー全体はnstat -azでTcpExtTCPTimeouts(再送タイマーの満了回数)の増加量を確認
- 該当する場合
- 止まった接続のbackoffが1以上で、rtoが秒単位まで大きくなっており、その時刻にTCPTimeoutsが増えている
- 該当しない場合
- 再送が高速再送で済み、RTOの満了がなければ停止は短い。その場合は「TCPのHOLブロッキング」
- 確認手段
- インフラのツールで確認(ゲームコード不要)
出典
- RFC 6298: Computing TCP's Retransmission Timer IETF
最初のRTOは1秒、タイマーが満了するたびにRTOを2倍に(指数バックオフ) - net/ipv4/tcp_input.c (Linux v6.12) Linux kernel
LinuxのRTO = 平滑化RTT + RTTの変動値で、変動値の下限がtcp_rto_min(200ms)のため、RTOはRTT+200ms以上 - IP Sysctl Linux kernel
tcp_rto_min_usのデフォルトは200ms、接続要求の最初のRTOは1秒、tcp_retries2=15ならあきらめるまで最低924.6秒(約15分) - ss(8) — Linux manual page iproute2
-iのrto(再送タイマー、ms)とbackoff(指数バックオフの回数) - net/ipv4/proc.c (Linux v6.12) Linux kernel
nstatが表示するカウンター名:TcpExtグループのTCPTimeouts - net/ipv4/tcp_timer.c (Linux v6.12) Linux kernel
再送タイマーが満了するたびにTCPTimeoutsを加算し、backoffを1つ増やしてRTOを2倍に(最大値まで)延ばす
あわせて読みたい原因
同じ層:L8 ソケットとプロトコル
同じ症状(フリーズ)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る