【実務・中級編】 netstatコマンドによるTCPコネクション状態(ESTABLISHED, TIME_WAIT等)の網羅的確認 – トラブルシューティング&ネットワーク運用監視実践ガイド

現場のエンジニアが「なんとなく」で終わらせない、netstatによるTCPソケット状態の深層

深夜3時、アラートが鳴り響く。監視ダッシュボードには「APIレスポンスの遅延」と「503 Service Unavailable」の文字。あなたは慌ててサーバーにSSHでログインし、真っ先に何を打ち込みますか?

多くのエンジニアが反射的に叩くコマンド、それが netstat です。しかし、出力された膨大なソケットリストを、あなたは単なる「数字の羅列」として見ていませんか?

本稿では、数々の修羅場を潜り抜けてきた私の経験に基づき、TCP状態遷移の裏側と、現場で本当に役立つ netstat(および後継の ss)の活用術を紐解いていきます。

—

TCP状態遷移を知れば、障害の半分は解決する

TCPは「3ウェイ・ハンドシェイク」と「4ウェイ・ハンドシェイク」という、厳格な握手と別れの儀式を経て通信を行います。netstat が出力する各ステータスは、その儀式の「現在地」を示しているに過ぎません。

特に注目すべきは以下の状態です。

  • ESTABLISHED: 正常な通信中。ここが異常に多い場合は、処理遅延やコネクションリークを疑う。
  • TIME_WAIT: 通信終了後の「余韻」。OSのTCPスタックが、遅れて届いたパケットを処理するために一定時間コネクションを保持する状態。これが多すぎると、新規接続用のポート枯渇(Ephemeral Port Exhaustion)を招く。
  • CLOSE_WAIT: 受信側が終了通知を受け取ったものの、アプリケーション側がまだ close() を発行していない状態。これは「コードのバグ」のサインである可能性が高い。

—

現場で使うべき「鉄板コマンド」

最近のディストリビューションでは netstat が非推奨となりつつありますが、まずは基本を押さえましょう。なお、現代の運用現場ではより高速な ss コマンドが主流です。

1. 接続状態を網羅的に確認する

# -n: 名前解決をしない(DNSの遅延に引きずられない)
# -t: TCPを表示
# -a: すべてのソケットを表示
# -p: ソケットを掴んでいるプロセスIDを表示(root権限必須)
sudo netstat -ntap | grep -E 'ESTABLISHED|TIME_WAIT'

2. 今、現場で最も推奨される「ss」コマンド

netstat は膨大なソケットがあると出力に時間がかかりますが、ss はカーネル内部の情報に直接アクセスするため爆速です。

# TIME_WAITをカウントして、負荷状況を秒単位で監視する
watch -n 1 'ss -tan state time-wait | wc -l'

—

現場の知見:CLOSE_WAIT と TIME_WAIT の罠

CLOSE_WAIT が発生する時

アプリケーションコードで、受信したストリームを適切にクローズしていないと、この状態がゾンビのように残ります。

# Pythonでの残念な例(クローズ漏れ)
import socket

def handle_request():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("api.example.com", 80))
    s.send(b"GET / HTTP/1.1\r\nHost: api.example.com\r\n\r\n")
    # ここで close() を呼び忘れると、サーバー側が切断しても
    # クライアント側のソケットは CLOSE_WAIT になり続ける

必ず try...finally ブロックや with 構文でソケットのクローズを担保してください。

TIME_WAIT が発生する時

Web APIサーバーを運用していると、大量の TIME_WAIT に頭を悩ませることがあります。これはTCPの仕様上避けられないものですが、極端に多い場合は、クライアント側(コネクションを頻繁に開閉する側)のOSチューニングが必要です。

/etc/sysctl.conf に以下の設定を検討してください。

# 既存のTIME_WAITソケットを新規接続に再利用する許可
net.ipv4.tcp_tw_reuse = 1

# エフェメラルポートの範囲を広げる
net.ipv4.ip_local_port_range = 1024 65535

—

最後に:ツールは「手段」に過ぎない

netstat や ss の出力を眺めていると、OSがどれだけ健気にパケットを捌こうとしているかが見えてきます。

障害対応の現場で最も重要なのは、「なぜその状態になったのか」という背景を想像する力です。クライアントがタイムアウトで切断したのか? それともサーバーのバックエンド処理が重すぎてスレッドが詰まったのか?

コマンドの出力結果は、ただの「結果」です。その背後にあるアプリケーションの挙動とパケットの流れを想像し、設計図と見比べたとき、初めてあなたは「エンジニア」として現場をコントロールできるようになります。

さあ、今日もターミナルを開いて、ネットワークの鼓動を感じに行きましょう。健闘を祈ります。

コメント

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