Bagaimana cara mengurangi jumlah soket di TIME_WAIT?

36

Ubuntu Server 10.04.1 x86

Saya memiliki mesin dengan layanan HTTP FCGI di belakang nginx, yang melayani banyak permintaan HTTP kecil untuk banyak klien yang berbeda. (Sekitar 230 permintaan per detik pada jam sibuk, ukuran respons rata-rata dengan header adalah 650 byte, beberapa juta klien berbeda per hari.)

Akibatnya, saya memiliki banyak soket, tergantung pada TIME_WAIT (grafik ditangkap dengan pengaturan TCP di bawah):

WAKTU MENUNGGU

Saya ingin mengurangi jumlah soket.

Apa yang bisa saya lakukan selain ini?

$ cat / proc / sys / net / ipv4 / tcp_fin_timeout
1
$ cat / proc / sys / net / ipv4 / tcp_tw_recycle
1
$ cat / proc / sys / net / ipv4 / tcp_tw_reuse
1

Pembaruan: beberapa detail pada tata letak layanan aktual pada mesin:

client ----- TCP-socket -> nginx (load balancer reverse proxy) 
       ----- TCP-socket -> nginx (pekerja) 
       --domain-socket -> fcgi-software
                          --single-persistent-TCP-socket -> Redis
                          --single-persistent-TCP-socket -> MySQL (komputer lain)

Saya mungkin harus mengganti load-balancer -> koneksi pekerja ke soket domain juga, tetapi masalah tentang soket TIME_WAIT akan tetap ada - saya berencana untuk menambahkan pekerja kedua di mesin yang terpisah segera. Tidak akan dapat menggunakan soket domain dalam kasus itu.

Alexander Gladysh
sumber
Tampaknya Munin berbohong tanpa malu-malu. Lihat komentar untuk jawaban Kyle. Melihat itu sekarang.
Alexander Gladysh
1
Membuat pertanyaan tentang Munin: serverfault.com/questions/212200/…
Alexander Gladysh
Sekarang sepertinya Munin tidak berbohong, tetapi saya melihat plot yang salah ...
Alexander Gladysh

Jawaban:

28

Satu hal yang harus Anda lakukan untuk memulai adalah memperbaiki net.ipv4.tcp_fin_timeout=1. Itu cara ke rendah, Anda mungkin tidak harus mengambil yang jauh lebih rendah dari 30.

Karena ini di belakang nginx. Apakah itu berarti nginx bertindak sebagai proxy terbalik? Jika itu yang terjadi maka koneksi Anda 2x (satu ke klien, satu ke server web Anda). Apakah Anda tahu di mana ujung soket ini milik?

Pembaruan:
fin_timeout adalah berapa lama mereka tinggal di FIN-WAIT-2 (Dari networking/ip-sysctl.txtdalam dokumentasi kernel):

tcp_fin_timeout - INTEGER
        Time to hold socket in state FIN-WAIT-2, if it was closed
        by our side. Peer can be broken and never close its side,
        or even died unexpectedly. Default value is 60sec.
        Usual value used in 2.2 was 180 seconds, you may restore
        it, but remember that if your machine is even underloaded WEB server,
        you risk to overflow memory with kilotons of dead sockets,
        FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
        because they eat maximum 1.5K of memory, but they tend
        to live longer. Cf. tcp_max_orphans.

Saya pikir Anda mungkin hanya perlu membiarkan Linux menjaga nomor soket TIME_WAIT melawan apa yang tampak seperti mungkin 32k tutup pada mereka dan ini adalah tempat Linux mendaur ulang mereka. 32k ini disinggung dalam tautan ini :

Juga, saya menemukan / proc / sys / net / ipv4 / tcp_max_tw_buckets membingungkan. Meskipun defaultnya ditetapkan pada 180000, saya melihat gangguan TCP ketika saya memiliki soket TIME_WAIT 32K di sistem saya, terlepas dari maks tw bucket.

Tautan ini juga menunjukkan bahwa status TIME_WAIT adalah 60 detik dan tidak dapat disetel melalui proc.

Fakta menyenangkan acak:
Anda dapat melihat penghitung waktu pada timewait dengan netstat untuk setiap soketnetstat -on | grep TIME_WAIT | less

Reuse Vs Recycle:
Ini agak menarik, berbunyi seperti reuse mengaktifkan penggunaan kembali soket time_Wait, dan mendaur ulang memasukkannya ke mode TURBO:

tcp_tw_recycle - BOOLEAN
        Enable fast recycling TIME-WAIT sockets. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

tcp_tw_reuse - BOOLEAN
        Allow to reuse TIME-WAIT sockets for new connections when it is
        safe from protocol viewpoint. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

Saya tidak akan merekomendasikan menggunakan net.ipv4.tcp_tw_recycle karena menyebabkan masalah dengan klien NAT .

Mungkin Anda mungkin mencoba untuk tidak mengaktifkan keduanya dan melihat efeknya (Coba satu per satu dan lihat bagaimana mereka bekerja sendiri)? Saya akan menggunakan netstat -n | grep TIME_WAIT | wc -lumpan balik yang lebih cepat daripada Munin.

Kyle Brandt
sumber
1
@Kyle: nilai apa yang net.ipv4.tcp_fin_timeoutakan Anda rekomendasikan?
Alexander Gladysh
1
@Kyle: klien --TCP-socket -> nginx (proksi penyeimbang beban terbalik) --TCP-socket -> nginx (pekerja) --domain-socket -> fcgi-software
Alexander Gladysh
2
Saya akan mengatakan 30atau mungkin 20. Cobalah dan lihatlah. Anda memiliki banyak muatan sehingga banyak jenis TIME_WAIT masuk akal.
Kyle Brandt
1
@Kyle: maaf untuk pertanyaan bodoh (sayangnya, saya berada di level kargo-kultus sejauh ini), tapi apa sebenarnya yang harus saya lihat ketika saya beralih net.ipv4.tcp_fin_timeoutdari 1ke 20?
Alexander Gladysh
4
Oh, di sini adalah salah satu kapal yang bagus: netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c. Jadi @Alex, jika Munin tidak suka, mungkin menelusuri bagaimana memantau statistik ini. Mungkin satu-satunya masalah adalah bahwa Munin memberi Anda data buruk :-)
Kyle Brandt
1

tcp_tw_reuse relatif aman karena memungkinkan koneksi TIME_WAIT untuk digunakan kembali.

Anda juga dapat menjalankan lebih banyak layanan dengan mendengarkan port yang berbeda di belakang load-balancer Anda jika kehabisan port merupakan masalah.

andrew pate
sumber