🌐
詳解 システム・パフォーマンス - 第10章:ネットワーク分析
TCP/IP・NICレート・TCPリトランスミッション・接続状態分析。ss/sar/tcpretrans/tcplifeの実践的な使い方とネットワークUSE法。
ネットワークのUSE法
| リソース | Utilization | Saturation | Errors |
|---|---|---|---|
| NIC | sar -n DEV の %ifutil | ip -s link の drop 数 | ip -s link の errors |
| TCP | 接続数 / 最大接続数 | sar -n TCP の retrans | sar -n ETCP のエラー |
| ソケットバッファ | 受信/送信バッファ使用率 | ss -m の buffer overflow | netstat -s |
基本確認コマンド
NIC の統計
# NIC の送受信レート(1秒間隔)
sar -n DEV 1 5
# IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
# eth0 10000.0 5000.0 125.0 62.5 0.0 0.0 0.0
# ポイント:
# rxkB/s + txkB/s が NIC の帯域(1Gbps = 125MB/s)に近い → NIC 飽和
# 10Gbps NIC = 1250 MB/s が理論最大
# NIC の詳細統計(エラー・ドロップ)
ip -s link show eth0
# RX: bytes packets errors dropped overrun mcast
# 100G 10M 0 0 0 0
# NIC の設定確認
ethtool eth0
# Speed: 10000Mb/s
# Duplex: Full
# Link detected: yes
TCP 統計
# TCP の状態統計
sar -n TCP,ETCP 1 5
# active/s: 新規接続の開始数(client 側)
# passive/s: 新規接続の受け入れ数(server 側)
# retrans/s: TCP リトランスミッション数 ← 0 に近いほど良い
# retrans/s > 1 → パケットロスが発生している(ネットワーク品質問題)
# TCP の状態集計(ss を使う)
ss -s
# Total: 500
# TCP: 350 (estab 200, closed 50, orphaned 10, timewait 100)
# 接続数の詳細
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
# 200 ESTABLISHED
# 100 TIME-WAIT
# 50 CLOSE-WAIT ← アプリが接続を閉じていない可能性
ss コマンドの完全ガイド
netstat の後継。ss を使う。
# リッスンポート一覧(プロセス名付き)
ss -tlnp
# -t: TCP / -l: LISTEN / -n: 名前解決なし / -p: プロセス名
# 確立済み接続(プロセス名付き)
ss -tnp
# ESTAB 0 0 192.168.1.1:8080 10.0.0.5:54321 users:(("java",pid=1234,fd=10))
# 特定ポートの接続
ss -tnp | grep :5432 # PostgreSQL への接続
# ソケットバッファ情報
ss -tnm
# Recv-Q: 受信バッファに溜まっているデータ(0以外 → アプリの読み出しが追いつかない)
# Send-Q: 送信バッファに溜まっているデータ(0以外 → ネットワークが遅い or 受信側が遅い)
# TIME-WAIT 状態の接続数(多すぎると問題になることがある)
ss -tan state time-wait | wc -l
# CLOSE-WAIT が多い(アプリのバグの可能性)
ss -tan state close-wait | head -10
TCP 接続状態の読み方
SYN_SENT → (3-way handshake) → ESTABLISHED → FIN_WAIT → TIME_WAIT → CLOSED
| 状態 | 意味 | 問題の兆候 |
|---|---|---|
ESTABLISHED | 接続中(正常) | 多すぎる = 接続プールが溢れている |
TIME_WAIT | 接続終了後の待機(正常) | 非常に多い = 短命接続が多い(keep-alive 推奨) |
CLOSE_WAIT | アプリが接続を閉じていない | 増加 = アプリのバグ(close() を呼んでいない) |
SYN_RECV | 接続受け付け中 | 大量 = SYN Flood 攻撃の可能性 |
FIN_WAIT2 | 相手の FIN 待ち | 増加 = ネットワーク問題 |
BCC tools でネットワークをトレース
# TCP 接続の開始をリアルタイムで追跡
sudo tcpconnect
# PID COMM IP SADDR DADDR DPORT
# 1234 java 4 192.168.1.1 10.0.0.5 5432 ← DB への接続
# TCP 接続の受け入れを追跡
sudo tcpaccept
# TCP リトランスミッションを検出(パケットロスの証拠)
sudo tcpretrans
# TIME PID IP LADDR:LPORT RADDR:RPORT STATE TYPE
# 12:00 1234 4 192.168.1.1:8080 10.0.0.5:54321 ESTAB R ← 再送信
# TCP セッションの詳細ログ(接続時間・データ量)
sudo tcplife
# PID COMM LADDR LPORT RADDR RPORT TX_KB RX_KB MS
# 1234 nginx 0.0.0.0 80 10.0.0.5 54321 0.5 10.2 25.3
# TCP レイテンシ(RTT)の分布
sudo tcpsynbl # SYN バックログの状態
# bpftrace で TCP 接続の接続先を集計
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_connect {
@connections[pid, comm] = count();
}
' -c "sleep 30"
ネットワークレイテンシの分析
# RTT の測定
ping -c 100 target_host
# 平均と最大の差が大きい → ジッターが多い(ネットワーク不安定)
# DNS 解決時間の確認
time dig +short example.com
# DNS が遅い場合、アプリのレイテンシ増加の原因になる
# HTTP レイテンシの詳細(curl の -w オプション)
curl -w "
DNS: %{time_namelookup}s
Connect: %{time_connect}s
TLS: %{time_appconnect}s
TTFB: %{time_starttransfer}s
Total: %{time_total}s
" -o /dev/null -s http://example.com/api/health
# tcpdump でパケットキャプチャ(詳細デバッグ)
sudo tcpdump -i eth0 -w capture.pcap host 10.0.0.5 and port 8080
# wireshark で分析: tcpretransmissions, TCP window size 等
ネットワークチューニング
TCP バッファサイズ
# 現在の設定
sysctl net.core.rmem_max # 最大受信バッファ
sysctl net.core.wmem_max # 最大送信バッファ
sysctl net.ipv4.tcp_rmem # TCP 受信バッファ(min/default/max)
sysctl net.ipv4.tcp_wmem # TCP 送信バッファ
# 高スループットが必要な場合の設定例
sysctl -w net.core.rmem_max=134217728
sysctl -w net.core.wmem_max=134217728
sysctl -w net.ipv4.tcp_rmem="4096 87380 134217728"
sysctl -w net.ipv4.tcp_wmem="4096 65536 134217728"
TIME_WAIT と接続数
# TIME_WAIT の再利用(短命接続が多い場合)
sysctl -w net.ipv4.tcp_tw_reuse=1
# バックログキュー(同時接続受け付け数)
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
# 確認
ss -s | grep TCP
ネットワーク問題のチェックリスト
□ sar -n DEV 1 で NIC の帯域使用率を確認(1Gbps = 125MB/s 上限)
□ sar -n TCP,ETCP で retrans/s を確認(> 1 でパケットロス疑い)
□ ss -s で TCP 状態の内訳を確認
□ CLOSE_WAIT が多い場合:アプリのコネクション close 漏れを調査
□ TIME_WAIT が非常に多い場合:keep-alive の設定を確認
□ tcpretrans でリトランスミッションが発生しているか確認
□ ping で RTT とジッターを測定
□ DNS 解決が遅くないか確認(dig / time dig)
□ ソケットバッファ(Recv-Q/Send-Q)が溜まっていないか(ss -tnm) - 1. 📊詳解 システム・パフォーマンス - 概要・読み方ガイド
- 2. 🔍詳解 システム・パフォーマンス - 第16章:ケーススタディ
- 3. 🧭詳解 システム・パフォーマンス - 第2章:メソドロジ
- 4. 🐧詳解 システム・パフォーマンス - 第3章:オペレーティングシステム
- 5. 🔭詳解 システム・パフォーマンス - 第4章:可観測性ツール
- 6. ⚙️詳解 システム・パフォーマンス - 第5章:アプリケーション
- 7. 💻詳解 システム・パフォーマンス - 第6章:CPU分析
- 8. 🧠詳解 システム・パフォーマンス - 第7章:メモリ分析
- 9. 📁詳解 システム・パフォーマンス - 第8章:ファイルシステム分析
- 10. 💾詳解 システム・パフォーマンス - 第9章:ディスク分析
- 11. 🌐詳解 システム・パフォーマンス - 第10章:ネットワーク分析
- 12. ☁️詳解 システム・パフォーマンス - 第11章:クラウドコンピューティング
- 13. 📏詳解 システム・パフォーマンス - 第12章:ベンチマーキング
- 14. 🔥詳解 システム・パフォーマンス - 第13章:perf
- 15. 🔬詳解 システム・パフォーマンス - 第14章:Ftrace
- 16. ⚡詳解 システム・パフォーマンス - 第15章:BPF/eBPF
出典: 詳解 システム・パフォーマンス 第2版 Brendan Gregg著