【入門編】 TIME_WAIT状態のソケット枯渇問題とTIME_WAITオークションの防止 – トラブルシューティング&ネットワーク運用監視実践ガイド

みなさん、こんにちは!グローバルなネットワークオペレーションセンター(NOC)で、日々飛び交うパケットと格闘しているシニアエンジニアの「タカ」です。

突然ですが、Webサービスを運用していて「アクセスが急増したわけでもないのに、なぜか突然サーバーが新しい接続を受け付けなくなってしまった…」という不気味なトラブルに遭遇したことはありませんか?

サーバーのCPUやメモリは余裕たっぷりなのに、なぜか繋がらない。実はこの裏で、「TIME_WAIT(タイム・ウェイト)」と呼ばれるネットワークの「お片付け待ちの亡霊」が大量発生し、通信の窓口を埋め尽くしていることがよくあるのです。

一見難しそうに思えるこの問題ですが、仕組みさえ分かれば怖くありません。今回は、インフラやネットワークの冒険を始めたばかりのあなたに向けて、郵便配達や身近な例えを交えながら、この「TIME_WAIT 枯渇問題」の正体と、そのスマートな解決法を優しく丁寧に紐解いていきます。一歩ずつ、一緒に理解していきましょう!

—

1. そもそも TIME_WAIT ってなに?(郵便配達に例えてみよう)

まずは、ネットワークでデータがやり取りされる基本のルールからお話しします。

インターネットで広く使われている TCP(ティー・シー・ピー) というお約束(プロトコル)では、データを送る前に「これから送るよ!」「いいよ!」と、お互いにしっかり握手をしてから会話を始めます。そして、会話が終わるときも「もう送るものはないよ」「了解、バイバイ!」とお互いに確認し合ってから通信を終了します。

この「バイバイ」の手続きの最後に登場するのが TIME_WAIT 状態です。

郵便配達で例える TIME_WAIT の役割

あなたが郵便で、大事な書類を相手に送ってやり取りを終える場面を想像してみてください。

1. あなた:「これで用件は終わりです(FIN)」
2. 相手:「了解しました。こちらからも、これで終わりです(FIN)」
3. あなた:「はーい、お疲れ様でした!(ACK)」

これで終わり…と思いきや、あなたは「最後に出した『お疲れ様でした!』の手紙が、もし途中で雨に濡れて消えたり、郵便事故で相手に届かなかったらどうしよう?」と不安になりませんか?

もし最後の手紙が届かなかったら、相手は「あれ?最後の手紙が来ないぞ。もう一度送るね」と、古い手紙を再送してくるかもしれません。

そこで、あなたは「念のため、相手が完全に納得して片付けを終えるであろう時間(一般的には1分〜2分ほど)だけ、机の上の資料を片付けずに、少しの間待機する」ことにしました。

この「念のための待機時間」こそが、ネットワークの世界における TIME_WAIT 状態 なのです。

—

2. なぜ TIME_WAIT が多すぎると困るの?(「窓口のパンク」問題)

TIME_WAIT は、通信を安全に、確実に終わらせるための「優しさ(安全対策)」です。しかし、これが大量に発生すると、システムに悪影響を及ぼし始めます。

サーバーの「窓口(ポート)」には限りがある

ネットワークの通信では、接続ごとに「ポート」と呼ばれる窓口が使われます。
例えば、あなたがWebサイトを見るとき、サーバー側は 80 番や 443 番といった決まった窓口で待ち受けますが、接続する側のあなたのパソコン(クライアント)や、サーバーから別のデータベースに接続する際は、32768 〜 60999 といった範囲の「空いている窓口(一時ポート)」をランダムに1つ使って通信します。

この窓口の数には、システム全体で上限があります(最大でも6万個程度です)。

もし、1秒間に何千回ものアクセスがある高負荷なWebサーバーだった場合、どうなるでしょうか?

  • 1秒間に大量の通信が生まれては、一瞬で終わる。
  • 終わった通信は、すべて TIME_WAIT 状態になり、1〜2分間「お片付け待ち」として窓口を占有し続ける。
  • 新しいお客さんが来ても、「どこの窓口もお片付け待ちの書類(TIME_WAIT)で埋まっていて、空いている窓口がない!」という状態になります。

これがいわゆる 「ソケット(ポート)枯渇問題」 です。サーバーの処理能力には余裕があるのに、通信の出入り口が塞がってしまうため、新規の接続がすべてシャットアウトされてしまうのです。

—

3. 現場で役立つ確認コマンド(ss と netstat)

「もしかして、うちのサーバーも TIME_WAIT で苦しんでいるのかな?」と思ったら、コマンドを使ってサーバーの中を覗いてみましょう。

昔から使われている netstat コマンドや、より高速でモダンな ss コマンドを使うことで、いまサーバーにどれだけの「お片付け待ち」があるかを一発で確認できます。

現在の TIME_WAIT の数を確認するコマンド

サーバーのターミナル(黒い画面)で、以下のコマンドを実行してみましょう。

# ssコマンドを使って、TIME_WAIT状態の接続数をカウントします
ss -an | grep TIME-WAIT | wc -l

# もしくは、従来のnetstatコマンドを使う場合(どちらでも同じような結果が得られます)
netstat -an | grep TIME_WAIT | wc -l

もし、このコマンドの結果が「数万」という大きな数字になっていたら、サーバーの窓口が枯渇寸前、あるいはすでにパンクしているサインです!

さらに、どの通信が溜まっているかを詳しく見るには、以下のようにたたきます。

# 接続の状態ごとに、現在いくつのソケットがあるかを一覧表示します
# (awkという便利なツールを使って、状態ごとにきれいに集計しています)
ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c

実行すると、以下のような結果が返ってきます。

12 ESTAB      # 現在アクティブに会話中の接続
 45000 TIME-WAIT  # お片付け待ちで眠っている接続(これが多すぎると危険!)
    5 LISTEN     # お客さんを待っている状態の窓口

これを見ると、実際に動いている接続(ESTAB)はたったの12個なのに、お片付け待ち(TIME-WAIT)が45,000個もあることがわかりますね。これこそが、トラブルの原因です。

—

4. 解決の処方箋:カーネルパラメーターの調整

では、この溢れかえった TIME_WAIT をどうやって解決すればいいのでしょうか?
Linuxカーネル(OSの心臓部)の設定を調整することで、この問題をスマートに解決できます。

⚠️ 注意!かつての「禁断の薬」tcp_tw_recycle は絶対に使わない

昔の技術ブログなどを見ると、「net.ipv4.tcp_tw_recycle を 1(有効)にしよう!」と書かれていることがあります。

しかし、これは現代のインターネットでは「絶対にやってはいけない設定」です。

この設定は、お片付け待ちの時間を強引に極限まで短縮するものですが、郵便配達に例えると「相手が誰だか確認する前に、届いた手紙をポイポイ捨てる」ような乱暴な処理を行います。
その結果、同じルーターやWi-Fi(NAT環境)を共有している複数のユーザーからのアクセスを「古い通信の残りカス」と勘違いして、正常なお客さんからのアクセスを容赦なく遮断してしまうという大障害を引き起こします。あまりにも危険なため、最新のLinuxカーネルではこの設定項目自体が削除されています。

✅ 安全な解決策:tcp_tw_reuse を使おう

私たちが安全に使える武器は、net.ipv4.tcp_tw_reuse(ソケットの再利用)です。

これは、「お片付け待ち(TIME_WAIT)になっている窓口であっても、安全だと確認できれば、新しい接続のためにその窓口を使い回して(再利用して)も良い」というルールを許可する設定です。

設定を有効にするには、/etc/sysctl.conf という設定ファイルに以下の行を書き加えます。

# /etc/sysctl.conf の末尾に以下を追記します

# TIME_WAIT状態のソケットを、安全な場合に限り新しい接続で再利用することを許可します
net.ipv4.tcp_tw_reuse = 1

# 一時的に利用するポート(窓口)の範囲を広げて、使える窓口そのものを増やします
net.ipv4.ip_local_port_range = 10240 65535

設定を書き換えたら、以下のコマンドを実行してシステムに即座に反映させましょう。

# 設定ファイルを読み込んで、変更をシステムに反映します
sudo sysctl -p

これで、サーバーは TIME_WAIT で窓口が埋まりそうになっても、賢く窓口をリサイクルして使い回すことができるようになります。

—

5. まとめ:パケットの気持ちに寄り添う運用を

お疲れ様でした!今回は TIME_WAIT 枯渇問題の仕組みと、その解決策について解説しました。

最後に、今回のポイントを振り返ってみましょう。

1. TIME_WAIT はエラーではない:通信を安全に終わらせるための、優しくて必要な「お片付け待ち時間」。
2. 高負荷時にパンクの原因になる:あまりに短い通信が大量に発生すると、すべての窓口が「片付け待ち」で埋まってしまう。
3. ss コマンドで現状把握:まずは ss -ant で、どれだけの TIME-WAIT がいるかを目で確認する。
4. 安全に再利用する:古い危険な recycle 設定は避け、net.ipv4.tcp_tw_reuse を使って安全に窓口をリサイクルする。

ネットワークの世界は、目に見えないパケットたちが健気にルールを守って走り回ることで成り立っています。トラブルが起きたときは、「パケットたちは今、どんな気持ちでお片付けを待っているのかな?」と想像してみると、解決の糸口がきっと見つかりますよ。

これからも一歩ずつ、一緒にインフラの奥深い魅力を楽しんでいきましょう!質問や気になることがあれば、いつでもコメントで教えてくださいね。

コメント

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