【実務・中級編】 ssコマンドによるタイマー情報(Keep-Alive, Retransmit)の確認 – トラブルシューティング&ネットワーク運用監視実践ガイド

現場の「見えない断絶」を暴く:ssコマンドでTCPタイマーを視覚化する技術

夜中の3時、アラートの通知音で叩き起こされ、ダッシュボードの真っ赤なグラフを眺める。「APIのレイテンシが急増し、その後パケットロスが発生している」。そんな修羅場をくぐり抜けてきた諸君ならわかるはずだ。ネットワークの障害は、往々にして「ログには何も残らない」場所で起きる。

アプリケーション層で 504 Gateway Timeout を連発しているとき、我々NOCのエンジニアが真っ先に手を伸ばすのは、tcpdump や wireshark の巨大なパケットキャプチャではない。まずは、カーネルの直近の記憶を覗き込むことだ。

今日は、現代のインフラ運用における最強の武器の一つ、ss コマンドを用いた「TCPタイマー」の解読法について解説しよう。

—

なぜ ss でタイマーを見るのか

netstat がレガシーな遺物となりつつある今、後継の ss コマンドがなぜ優秀なのか。それは単に処理が速いからではない。カーネル内のソケット情報を、より詳細かつ低負荷に引き出せるからだ。

特に -o (option) オプションは、TCPの通信が今どんな「焦燥感」を抱えているかを教えてくれる。Keep-Aliveの残り時間や、再送(Retransmit)の試行回数。これらは、パケットがネットワークのどこかで「迷子」になっているか、あるいは対向サーバーが「沈黙」しているかを見極めるための羅列だ。

基本コマンドと出力の見方

まずは、手元のLinuxサーバーで以下のコマンドを叩いてみてほしい。

# -t: TCPソケットを表示
# -a: すべてのソケットを表示
# -n: 数値形式(名前解決しない)
# -o: タイマー情報を表示
ss -tan -o

出力の末尾に、timer:(...) という奇妙な文字列が見えるはずだ。これが今回扱う核心部分である。

—

タイマーの正体:RFCの向こう側

出力される値は、主に以下の3つのタイマーを指している。

1. on (Retransmit timer): パケットを送信したがACKが返ってこない状態。ss は「あと何ミリ秒で再送を開始するか」を表示する。ここが頻繁に動いているなら、物理回線の輻輳か、パケットドロップを疑え。
2. keepalive (Keep-Alive timer): アイドル状態の接続を維持するためのタイマー。HTTP/1.1の Connection: keep-alive とは別に、OSレベルでコネクションが生きてるかを確認するパルスだ。
3. timewait (Time-Wait timer): 接続終了後の「余韻」期間。これが溜まりすぎると、新しい接続を受け入れられなくなる(いわゆる「ポート枯渇」)。

—

現場での活用ケース:再送地獄を追跡する

APIサーバーが突如として「応答なし」になる現象を追うとき、我々はまず再送回数を確認する。

もし ss で以下のような出力が見えたら注意が必要だ。

ESTAB  0  120  10.0.0.1:443  192.168.1.50:56782  timer:(on,200ms,0)

この timer:(on, 200ms, 0) の意味は、「200ms後に最初の再送を試みる(on)、現在の試行回数は0」ということだ。もし、この数値が 1.2s、2.4s と指数関数的に増えていくなら、ネットワークのどこかでブラックホールが発生している。

Pythonによる検証用コード

実際に、わざとパケットを捨てて ss で確認するための簡単なツールを書いてみた。

import socket

# 特定のサーバーへ接続し、敢えて何も送らずに放置してKeep-Aliveを観察する
def check_socket_state():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("127.0.0.1", 8080))
    # Keep-Aliveを有効にする
    s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
    
    # この状態でCLIから ss -tan -o を実行すると、
    # keepaliveタイマーがカウントダウンされているのが見えるはずだ
    input("何かキーを押すと閉じます...")
    s.close()

if __name__ == "__main__":
    check_socket_state()

—

運用上のTips:なぜ「沈黙」は起きるのか

実務において、このタイマー情報を駆使して解決した事例を一つ挙げよう。

ある日、Web APIの通信が特定のクライアントだけ異常に遅いという報告があった。ログを追うと、クライアントからのリクエストは届いているが、レスポンスが「再送(Retransmit)」を繰り返している。

ss で確認したところ、timer:(on, ...) の再送回数が異常に伸びていた。原因を辿ると、途中のロードバランサー(L4スイッチ)のMTU設定がミスっており、大きなパケットだけがドロップしていたのだ。curl でサイズを指定して通信テストを繰り返したことで、問題のパケットサイズを特定できた。

現場で役立つコマンドラインTips

トラブルシューティング時は、以下のように watch を組み合わせて「変化」を観察するのが鉄則だ。

# 2秒ごとにソケット状態を監視し、再送タイマーの変化をリアルタイムで追う
watch -n 2 "ss -tan -o | grep -v 'ESTAB'"

—

最後に:ネットワークを「感じる」こと

ネットワークエンジニアの仕事は、画面上の数字を現実の物理挙動に翻訳することだ。ss のタイマー情報は、単なるカーネルの変数ではない。それは、遠く離れたサーバーが「まだ生きていますか?」と不安げに問いかけている鼓動そのものだ。

教科書的な RFC793(TCP仕様)を暗記するだけでは足りない。現場でトラブルが起きたとき、そのタイマーの数字が「急激に増えているのか」、それとも「微動だにしないのか」を読み解く感性を磨いてほしい。

次に障害対応の現場に立ったとき、まずは ss -tan -o を叩いてみてほしい。そこには、君の知らないネットワークの真実が刻まれているはずだ。健闘を祈る。

コメント

タイトルとURLをコピーしました