現場の「駆け込み寺」:netstatが教えてくれる、プロセスとソケットの泥臭い真実
障害発生時の午前3時、真っ暗なデータセンターで監視画面を見つめながら、真っ先に叩くコマンドは何だろうか。tcpdump? それもいい。だが、アプリケーションが「なぜか繋がらない」「応答が返ってこない」という時、真っ先に確認すべきは、OSのカーネルがそのポートを本当に監視しているのか、そして背後のプロセスが正しく生きていられるかだ。
今回は、今や「レガシー」の烙印を押されつつあるが、未だに現場で最強の武器となり得る netstat コマンドについて、あえて深掘りしてみたい。
なぜ netstat は未だに現役なのか
モダンなディストリビューションでは ss コマンドが推奨されている。これには異論はない。ss はカーネルの netlink インターフェースを直接叩くため、数万のコネクションが張られた高負荷サーバーでも、瞬時に結果を返す。
一方、netstat は /proc/net/ 以下のファイルを読み込んで整形する。このプロセスは、接続数が増えるほどCPU負荷が高まり、パフォーマンス面では分が悪い。しかし、我々エンジニアが netstat を愛してやまない理由は、その「枯れた挙動」と「UNIXドメインソケットへの深い理解」にある。
UNIXドメインソケットという「目に見えない裏口」
Web APIの設計やマイクロサービス運用で、最も頭を抱えるのが「ローカル通信のデッドロック」だ。例えば、NginxとPHP-FPM、あるいはGunicornの通信をTCPソケットではなく、UNIXドメインソケットで行うケースは多い。
この時、netstat は TCP/UDP と同じ土俵で、これらの「ファイルパス」を可視化してくれる。
# -l: リスニングポートを表示
# -n: 名前解決をしない(DNSの遅延でイライラしたくないため)
# -x: UNIXドメインソケットを表示
# -p: プロセスIDとプログラム名を表示(これが一番重要)
sudo netstat -lnxp | grep php
ここで重要なのは、Proto カラムが unix となっている行だ。RefCnt(参照カウント)が異常に増えていたり、State が LISTEN でないものがゾンビ化していないかを確認する。もし、APIのレスポンスが極端に遅い場合、このソケット越しにカーネル内部でI/O待ちが発生していることが非常に多い。
TCP/UDPの泥臭いデバッグ:シーケンスと状態遷移
ネットワークエンジニアとして、netstat の出力を眺める時は、常にその背後にあるTCPのステートマシンをイメージしている。
ESTABLISHED は健全だが、SYN_SENT が大量に残っているなら、接続先への経路でパケットがドロップされているか、相手側のListen backlogが溢れている可能性を疑う。
特に、Pythonで実装したAPIクライアントがタイムアウトを繰り返すような場合、以下のコードのように requests 等でソケットオプションを明示的に設定しつつ、netstat で状態を追うのが鉄則だ。
import requests
# タイムアウトを厳密に設定し、ソケットのハングを回避する
try:
response = requests.get(
"http://unix:/var/run/api.sock:/v1/data",
timeout=(3.05, 10) # 接続タイムアウトと読み込みタイムアウトを分離
)
print(response.status_code)
except requests.exceptions.RequestException as e:
# 接続失敗時、netstatで該当ポート/ソケットのステートを確認せよ
print(f"Connection failed: {e}")
現場のTips:netstat のパラメータをどう使いこなすか
後輩によく教えるのは、以下のエイリアス設定だ。netstat は入力が面倒だが、特定の組み合わせで情報の解像度が劇的に上がる。
# .bashrc 等に登録しておくべき、障害調査用コマンド
alias nss="netstat -tulpn"
-t: TCPを表示-u: UDPを表示-l: リスニング状態のソケットのみ-p: PIDを表示-n: 数値形式
このコマンドを打った時、Recv-Q や Send-Q の値に注目してほしい。ここがゼロ以外の数値で停滞しているなら、それはOSのバッファが埋まっており、アプリケーションが処理を追いつけていない「ボトルネックのサイン」だ。
まとめ:ツールは道具に過ぎない
netstat がレガシーであろうと最新の ss であろうと、結局のところ、我々が見ているのは「データが正しく流れ、適切なメモリ空間で処理されているか」という一点に尽きる。
障害対応の現場では、コマンドの出力結果をただ眺めるのではなく、「今、カーネルのどのメモリ領域でパケットが足止めを食らっているのか?」を想像する力が求められる。
もし次にWeb APIの挙動が怪しくなったら、まずは netstat -lnxp を叩いてみてほしい。そこには、教科書には載っていない、生々しいシステムの声が聞こえてくるはずだ。焦らず、一歩ずつレイヤーを降りていけば、必ず解決の糸口は見つかる。健闘を祈る。
コメント