【実務・中級編】 ssコマンドによるTCP状態遷移とソケット詳細情報の高速取得 – トラブルシューティング&ネットワーク運用監視実践ガイド

時代は netstat から ss へ:現場のエンジニアが「一瞬で」ソケットを覗き込む極意

夜中の3時、データセンターのフロアで轟音を響かせるサーバーの前に立ち、原因不明のTCP接続断を追っているとき。君ならどうやってボトルネックを探す?

かつて、我々エンジニアの相棒といえば netstat だった。だが、現代のLinux環境、特に数万の同時接続を捌くWeb APIサーバーにおいて、netstat を叩くのは「図書館で特定のページを探すために全蔵書を読み直す」ようなものだ。プロセスが増えれば増えるほど、/proc を舐め回す netstat は重くなり、肝心な瞬間にフリーズする。

そこで登場するのが ss(Socket Statistics)コマンドだ。カーネル直結の sock_diag インターフェースを叩くこのツールこそ、我々NOCエンジニアの現場での必須スキルである。

なぜ ss なのか:カーネルへの直接アクセス

netstat が /proc/net/ を走査して情報をかき集めるのに対し、ss はカーネル内部の sock_diag モジュールから情報を直接吸い上げる。これは、CPU負荷が極めて低いことを意味する。

数千のコネクションが張られた高負荷なAPIサーバーで、netstat -an を打って応答が返ってくるのを待つのはもうやめよう。ss を使えば、カーネルが保持している生の状態を、まるでレントゲン写真のように一瞬で引き抜ける。

実践:現場で使うべき基本コマンド

まずは、実務で最も頻繁に使うコマンドを頭に叩き込んでほしい。

# TCP接続のみを表示し、ポート番号を数値で表示し、プロセス名も併記する
# -t: TCP, -n: 数値表示, -p: プロセス名, -l: リッスン状態も含める
ss -tnpl

特に現場で重宝するのは、接続数が多い時のフィルタリングだ。特定のIPやポートに絞り込んで解析する際、grep をパイプで繋ぐのは二流のやり方。ss 自体のフィルタ機能を使え。

# 特定のポート(8080)に接続しているソケットだけを抽出
ss -nt '( dst :8080 )'

# 特定のステータス(TIME-WAIT)だけを抽出して数える
ss -nt state time-wait | wc -l

TCP状態遷移を ss で可視化する

APIサーバーが「502 Bad Gateway」を吐き出しているとき、真っ先に疑うべきは TIME-WAIT の大量滞留や、SYN-RECV によるバックログ溢れだ。

ss は、TCPの状態遷移を細かく追える。

# すべての接続状態をカウントする
ss -s

この出力に含まれる estab(Established)、timewait、syn-recv の数値を見るだけで、そのサーバーが今、どこで悲鳴を上げているかが手に取るようにわかる。例えば、timewait が数万を超えているなら、カーネルパラメータの net.ipv4.tcp_tw_reuse の見直しや、キープアライブ設定の最適化が必要だというサインだ。

Pythonによるリアルタイム監視への応用

監視ツールを自作する際も、ss の出力をパースするのは非常に効率的だ。以下は、現在確立されているコネクション数を1秒ごとに取得し、異常があればアラートを出す簡易的なPythonスクリプトの断片だ。

import subprocess

def get_established_count():
    # ssコマンドを実行して、ESTAB状態の接続数をカウント
    cmd = "ss -nt state established | wc -l"
    result = subprocess.check_output(cmd, shell=True)
    return int(result.decode().strip()) - 1  # ヘッダー行を引く

# 運用監視での活用例:接続数が閾値を超えたらログを出す
threshold = 5000
current = get_established_count()
if current > threshold:
    print(f"警報: 接続数が限界に達しています: {current}")

インフラエンジニアからのアドバイス:パケットの「呼吸」を感じろ

最後に、若手エンジニアによく言うことがある。「コマンドはツールに過ぎない。重要なのは、その裏側で何が起きているかを想像することだ」。

ss で SYN-RECV が溜まっているのを見たら、単に「接続が多い」と片付けてはいけない。クライアントからの ACK が届いていないのか、それともサーバー側の accept() システムコールが追いついていないのか。パケットの流れを想像し、ss でその一瞬を切り取る。この泥臭い積み重ねが、障害対応のスピードを劇的に変える。

今日から netstat は引退させて、ss でカーネルの鼓動を直接聞いてみてほしい。きっと、今まで見えなかったトラブルの予兆が、鮮明に見えてくるはずだ。

コメント

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