CPUもメモリも余裕があるのに接続が詰まる場合、Linuxカーネルのデフォルトパラメータがボトルネックになっていることが多い。特に「接続受付キューの上限」「TIME_WAIT接続の滞留」「TCP送受信バッファの不足」はデフォルト値が小規模サーバー向けのままで、本番の高負荷環境に合っていないことがある。
この記事では、net.core.somaxconn・tcp_max_syn_backlog・tcp_fin_timeout・tcp_rmem/tcp_wmemの各パラメータについて、何をしているか・現状確認コマンド・推奨設定値・永続化の手順を実機ベースで解説する。
実行環境:RHEL 9.4 / Rocky Linux 9.4 / Ubuntu 24.04 LTS で動作確認済み。
この記事のポイント
・somaxconnのデフォルト128は高負荷サーバーには低すぎる。4096以上を推奨
・tcp_tw_reuseはNATやロードバランサー配下では有効だが設定前に動作確認が必要
・tcp_rmem/tcp_wmemを広げると帯域効率は上がるがメモリ使用量も増える
・変更は/etc/sysctl.d/に.confを置いて永続化し、sysctl -pで即時反映する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜTCPチューニングが必要か
Linuxカーネルが持つTCP関連パラメータの多くは、数十年前のサーバー環境を想定したデフォルト値のまま出荷されている。例えば、接続受付キューの上限を決める
net.core.somaxconn はRHEL 9系でデフォルト4096に引き上げられているが、ディストリビューションやバージョンによっては128のままになっている。1秒間に数百の新規接続が来るWebサーバーでは、このキューがすぐに溢れてSYN_DROPが多発する。高負荷時に起きやすい主な症状を整理しておく。
・接続が突然切れる、タイムアウトが増える → 受付キュー溢れ or TIME_WAIT枯渇
・大量データ転送が遅い → TCPバッファ不足
・短時間に大量接続が来るとリセットが増える → SYNバックログ不足
いずれも、アプリ側のチューニングより先にカーネルパラメータを見直すと改善できることが多い。
チューニング前に現状を把握する
変更前に現在のパラメータ値とTCP接続の状態を記録しておく。後で「変更前後でどう変わったか」を比較するためだ。1. TCPパラメータの現在値を確認する
# チューニング対象パラメータを一覧で確認 sysctl -a 2>/dev/null | grep -E 'somaxconn|syn_backlog|fin_timeout|tw_reuse|tcp_mem|tcp_rmem|tcp_wmem'
# sysctl output on RHEL 9.4 (default values before tuning) net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 512 net.ipv4.tcp_fin_timeout = 60 net.ipv4.tcp_tw_reuse = 2 net.ipv4.tcp_mem = 182418 243227 364836 net.ipv4.tcp_rmem = 4096 131072 6291456 net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.somaxconn が4096、古いCentOS 7では128になっている場合がある。まず自分のサーバーの値を把握することが大切だ。2. TCP接続の現状を確認する
ss -s コマンドでTCPセッションの集計を確認する(Linux ポート確認の全コマンド)。ss -s
Total: 1842 TCP: 1347 (estab 312, closed 989, orphaned 1) Transport Total IP IPv6 RAW 2 2 0 UDP 18 10 8 TCP 358 342 16 INET 378 354 24 FRAG 0 0 0
接続受付キューを設定する(somaxconn・tcp_max_syn_backlog)
TCPの接続確立には「SYNキュー」と「ACCEPTキュー」の2段階がある。1. net.core.somaxconnとは
net.core.somaxconn はACCEPTキューの最大長を決める。アプリが accept() を呼ぶ前に「確立済み接続を積んでおけるバッファ」の上限だ。・デフォルト:ディストリビューションによって128または4096
・推奨値(高負荷Webサーバー):4096以上
・設定例:
sysctl -w net.core.somaxconn=4096
listen 80 backlog=4096; のように合わせて設定しないと効果が出ない。2. net.ipv4.tcp_max_syn_backlogとの違い
net.ipv4.tcp_max_syn_backlog は3ウェイハンドシェイクが完了する前の「SYNキュー」の最大長だ。SYNを受け取ったがACKがまだ来ていない接続を保持する。・デフォルト:512程度(カーネルバージョンやRAM容量によって変動)
・推奨値:somaxconnの2倍程度
・DDoSのSYNフラッドが心配な場合は
net.ipv4.tcp_syncookies=1(デフォルトで有効)と併用するsysctl -w net.ipv4.tcp_max_syn_backlog=8192
3. 設定後の確認
nginxのバックログと合わせた設定後、ss -lnt で確認する。# Recv-Q が 0 のまま安定しているかを確認(キュー溢れがないこと) ss -lnt sport = :80
State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 4096 0.0.0.0:80 0.0.0.0:*
接続タイムアウトを短縮する(tcp_fin_timeout / tcp_tw_reuse)
短時間に大量の接続を扱うサーバーでは、クローズ処理中の接続がポートを使いっぱなしにすることがある。TIME_WAITが溢れるとエフェメラルポートが枯渇し、新規接続ができなくなる。1. tcp_fin_timeoutを短縮する
FIN_WAIT_2状態の接続を保持し続ける秒数だ。デフォルトは60秒。短縮すると古い接続がはやく解放される。# 60秒 → 30秒に短縮する例 sysctl -w net.ipv4.tcp_fin_timeout=30
2. tcp_tw_reuseの注意点
tcp_tw_reuse=1 はTIME_WAIT状態のソケットを新規接続に再利用する設定だ。デフォルト2はループバック限定で有効。・値の意味:0=無効、1=有効(全インターフェース)、2=ループバックのみ有効(デフォルト)
・外部クライアントと大量通信するサーバーには
1 が有効だが、NATが絡む環境では予期しない動作を招くことがある・設定変更前に必ず開発環境でテストすること
# ループバック以外でも TIME_WAIT ソケットを再利用する sysctl -w net.ipv4.tcp_tw_reuse=1
3. TIME_WAIT接続数の確認
# TIME_WAIT 接続の数を数える ss -nat | grep TIME-WAIT | wc -l
sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 60999
送受信バッファサイズを最適化する(tcp_rmem / tcp_wmem)
大容量ファイルの転送や、高RTT(遠距離・WAN越し)環境でスループットが出ない場合は、TCP送受信バッファが原因のことがある。tcp_rmem は受信バッファ(受け取る側)、tcp_wmem は送信バッファ(送り出す側)を制御する。各パラメータには「最小値 デフォルト値 最大値」の3つを指定する。# 現在のバッファ設定を確認 sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem
net.ipv4.tcp_rmem = 4096 131072 6291456 net.ipv4.tcp_wmem = 4096 16384 4194304
1. バッファを拡張する目安
「帯域幅(bps) × RTT(秒)」が「帯域遅延積(BDP)」と呼ばれる。この値より小さいバッファでは理論帯域が出ない。例:100Mbps回線、RTT 20ms の場合
・BDP = 100,000,000 bps × 0.020秒 ÷ 8 = 250,000バイト(約244KB)
・デフォルトの最大6MBならこの環境では問題なし
・1Gbps、RTT 100msの場合:BDP = 12.5MB → デフォルト上限を超えるため拡張が必要
2. バッファを変更する例
# 最大値を16MBに拡張する例(高帯域・高RTT環境向け) sysctl -w net.ipv4.tcp_rmem="4096 131072 16777216" sysctl -w net.ipv4.tcp_wmem="4096 16384 16777216" # 自動チューニングの上限も合わせて設定する sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.wmem_max=16777216
設定を永続化する(/etc/sysctl.d/)
sysctl -w の変更は再起動で失われる。永続化するには /etc/sysctl.d/ 配下に設定ファイルを作成する。1. 設定ファイルを作成する
cat > /etc/sysctl.d/99-tcp-tuning.conf << 'EOF' # TCP受付キュー net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 8192 # 接続タイムアウト短縮 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 # 送受信バッファ(高負荷サーバー向け) net.ipv4.tcp_rmem = 4096 131072 16777216 net.ipv4.tcp_wmem = 4096 16384 16777216 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 EOF
2. 即時反映する
# 設定ファイルを読み込んで即時反映 sysctl -p /etc/sysctl.d/99-tcp-tuning.conf
net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 8192 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_rmem = 4096 131072 16777216 net.ipv4.tcp_wmem = 4096 16384 16777216 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216
/etc/sysctl.d/99-tcp-tuning.conf が自動で読み込まれ、設定が維持される。3. 設定済みか確認する
# 個別に確認する sysctl net.core.somaxconn sysctl net.ipv4.tcp_fin_timeout
net.core.somaxconn = 4096 net.ipv4.tcp_fin_timeout = 30
トラブルシュート:設定が反映されない・問題が起きた
1. sysctl -p で「Permission denied」が出る
rootまたはsudoで実行する。SELinuxが有効な環境では追加設定が必要な場合もある。sudo sysctl -p /etc/sysctl.d/99-tcp-tuning.conf
2. somaxconnを変えてもSend-Qが変わらない
アプリケーション(nginx・Apacheなど)のバックログ設定も合わせて変更する必要がある。nginxの例:# /etc/nginx/nginx.conf の listen ディレクティブ listen 80 backlog=4096; listen 443 ssl backlog=4096;
systemctl reload nginx を実行する。3. tcp_tw_reuseを有効にしたら接続が不安定になった
NATやロードバランサー経由の通信では、同一IP:ポートの組み合わせが短時間に再利用されると「古いパケット」と「新しいパケット」が混在してデータ破損が起きることがある。tcp_tw_reuse=2(ループバックのみ)に戻してから原因を調査する。sysctl -w net.ipv4.tcp_tw_reuse=2
4. バッファを拡大したらメモリが不足した
free -h でメモリ使用量を確認する。問題が起きた場合は最大値を半分に減らして様子を見る。# バッファ最大を8MBに下げる sysctl -w net.ipv4.tcp_rmem="4096 131072 8388608" sysctl -w net.ipv4.tcp_wmem="4096 16384 8388608"
本記事のまとめ
LinuxサーバーのTCPスタックチューニングで押さえるべきパラメータをまとめる。| パラメータ | デフォルト | 高負荷向け推奨値 | 効果 |
|---|---|---|---|
| net.core.somaxconn | 128 または 4096 | 4096以上 | ACCEPTキュー拡大 |
| net.ipv4.tcp_max_syn_backlog | 512程度 | 8192 | SYNキュー拡大 |
| net.ipv4.tcp_fin_timeout | 60秒 | 30秒 | FIN_WAIT_2短縮 |
| net.ipv4.tcp_tw_reuse | 2 | 1(ロードバランサー配下のみ) | TIME_WAIT再利用 |
| net.ipv4.tcp_rmem(最大) | 6MB | 16MB(高RTT環境) | 受信スループット向上 |
| net.ipv4.tcp_wmem(最大) | 4MB | 16MB(高RTT環境) | 送信スループット向上 |
チューニングの手順は「現状確認(sysctl -a・ss -s)→ 変更(sysctl -w)→ 動作確認(ss -lnt / ss -nat)→ 永続化(/etc/sysctl.d/)」の順で進めること。1つずつ変更して効果を確認するのが現場での鉄則だ。
「高負荷でも落ちないサーバー」は、TCPスタック含めた設計の「型」から生まれます
本番環境で障害が起きてから「somaxconnが足りなかった」と気づくのでは遅い。カーネルパラメータを含めたLinuxサーバーの設計をあらかじめ習得しておくことが、安定運用への最短ルートだ。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:fioコマンドでLinuxサーバーのディスクI/Oをベンチマークする方法|ランダム読み書き・シーケンシャル・混在の実測手順
- この記事の属するカテゴリ:Linuxトラブルシューティングへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます