한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

ゲームラグ白書 › 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ブロッキング」
確認手段
インフラのツールで確認(ゲームコード不要)

出典

  1. RFC 6298: Computing TCP's Retransmission Timer IETF
    最初のRTOは1秒、タイマーが満了するたびにRTOを2倍に(指数バックオフ)
  2. net/ipv4/tcp_input.c (Linux v6.12) Linux kernel
    LinuxのRTO = 平滑化RTT + RTTの変動値で、変動値の下限がtcp_rto_min(200ms)のため、RTOはRTT+200ms以上
  3. IP Sysctl Linux kernel
    tcp_rto_min_usのデフォルトは200ms、接続要求の最初のRTOは1秒、tcp_retries2=15ならあきらめるまで最低924.6秒(約15分)
  4. ss(8) — Linux manual page iproute2
    -iのrto(再送タイマー、ms)とbackoff(指数バックオフの回数)
  5. net/ipv4/proc.c (Linux v6.12) Linux kernel
    nstatが表示するカウンター名:TcpExtグループのTCPTimeouts
  6. net/ipv4/tcp_timer.c (Linux v6.12) Linux kernel
    再送タイマーが満了するたびにTCPTimeoutsを加算し、backoffを1つ増やしてRTOを2倍に(最大値まで)延ばす

あわせて読みたい原因

同じ層:L8 ソケットとプロトコル

同じ症状(フリーズ)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る