Apa yang membatasi jumlah maksimum koneksi pada server Linux?

89

Apa parameter kernel atau pengaturan lain yang mengontrol jumlah maksimum soket TCP yang dapat dibuka di server Linux? Apa pengorbanan dari memungkinkan lebih banyak koneksi?

Saya perhatikan saat memuat pengujian server Apache dengan ab bahwa itu cukup mudah untuk memaksimalkan koneksi terbuka di server. Jika Anda mematikan opsi ab's -k, yang memungkinkan koneksi digunakan kembali, dan meminta lebih dari 10.000 permintaan, maka Apache melayani 11.000 permintaan pertama dan kemudian berhenti selama 60 detik. Pandangan terhadap output netstat menunjukkan 11.000 koneksi dalam status TIME_WAIT. Ternyata, ini normal. Koneksi tetap terbuka default 60 detik bahkan setelah klien selesai dengan mereka untuk alasan keandalan TCP .

Sepertinya ini akan menjadi cara mudah untuk melakukan DoS server dan saya bertanya-tanya apa penyetelan dan tindakan pencegahan yang biasa untuk itu.

Inilah hasil pengujian saya:

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

Inilah perintah netstat yang saya jalankan selama pengujian:

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab
Ben Williams
sumber

Jawaban:

64

Saya akhirnya menemukan pengaturan yang benar-benar membatasi jumlah koneksi: net.ipv4.netfilter.ip_conntrack_max. Ini ditetapkan ke 11.776 dan apa pun yang saya atur adalah jumlah permintaan yang dapat saya layani dalam pengujian saya sebelum harus menunggu beberapa tcp_fin_timeoutdetik agar lebih banyak koneksi tersedia. The conntrackmeja adalah apa yang menggunakan kernel untuk melacak keadaan koneksi sehingga setelah penuh, kernel mulai menjatuhkan paket dan mencetak ini dalam log:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

Langkah selanjutnya adalah membuat kernel untuk mendaur ulang semua koneksi di TIME_WAITnegara daripada menjatuhkan paket. Saya bisa mewujudkannya dengan menyalakan tcp_tw_recycleatau menambah ip_conntrack_maxlebih besar dari jumlah port lokal yang tersedia untuk koneksi ip_local_port_range. Saya kira begitu kernel keluar dari port lokal itu mulai mendaur ulang koneksi. Ini menggunakan lebih banyak koneksi pelacakan memori tetapi sepertinya solusi yang lebih baik daripada menghidupkan tcp_tw_recyclekarena dokumen menyiratkan bahwa itu berbahaya.

Dengan konfigurasi ini saya dapat menjalankan ab sepanjang hari dan tidak pernah kehabisan koneksi:

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

The tcp_max_orphansPengaturan tidak memiliki efek pada tes saya dan saya tidak tahu mengapa. Saya akan berpikir itu akan menutup koneksi dalam TIME_WAITkeadaan begitu ada 8192 dari mereka tetapi tidak melakukan itu untuk saya.

Ben Williams
sumber
3
Di mana kita mengkonfigurasi params ini?
Codevalley
2
@Codevalley Itu mungkin tergantung pada sistem tetapi pada Ubuntu Server mereka masuk /etc/sysctl.conf
Ben Williams
24

Anda benar-benar ingin melihat apa yang ditawarkan sistem file / proc dalam hal ini.

Pada halaman terakhir itu, Anda mungkin menemukan yang berikut ini menarik bagi Anda:

Avery Payne
sumber
tcp_max_orphans menarik tetapi sepertinya itu tidak berfungsi. Ketika saya mencoba mengukur soket yatim piatu selama pengujian saya, saya melihat 11.651 dari mereka sementara tcp_max_orphans adalah 8.092. # netstat --inet -p | grep "localhost: www" | sed -e 's / \ + / / g' | cut -d '' -f 1-4,6-7 | sortir | uniq -c 11651 tcp 0 0 localhost: www TIME_WAIT -
Ben Williams
Lihatlah pengaturan tcp_orphan_retries - idenya, soketnya "dimusnahkan" lebih cepat ...
Avery Payne
Saran @Jauder Ho + tcp_orphan_retries terdengar seperti kemenangan potensial untuk situasi Anda.
Avery Payne
3

Saya tidak berpikir ada yang bisa diatur untuk mengaturnya secara langsung. Ini termasuk dalam kategori penyetelan TCP / IP. Untuk mengetahui apa yang dapat Anda sesuaikan, cobalah 'man 7 tcp'. Sysctl ('man 8 sysctl') digunakan untuk mengatur ini. 'sysctl -a | grep tcp 'akan menunjukkan kepada Anda sebagian besar dari apa yang dapat Anda sesuaikan, tetapi saya tidak yakin apakah itu akan menampilkan semuanya. Selain itu, kecuali jika ini telah berubah, soket TCP / IP akan terbuka seperti deskriptor file. Jadi ini dan bagian selanjutnya di tautan itu mungkin yang Anda cari.

Kyle Brandt
sumber
2

Coba atur yang berikut ini juga dengan mengatur tcp_fin_timeout. Ini harus menutup TIME_WAIT lebih cepat.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
Jauder Ho
sumber
Hati-hati di sini! Mengalami cara yang sulit. "Ini dapat menyebabkan frame terjatuh dengan load-balancing dan NATs, hanya gunakan ini untuk server yang berkomunikasi hanya melalui jaringan lokal Anda." - wiki.archlinux.org/index.php/Sysctl
Henk
@ Henk Saya kira itu tcp_tw_recycleberpotensi berbahaya. tcp_tw_reuselebih aman dan saya tidak melihat alasan untuk menggunakannya secara bersamaan.
Vladislav Rastrusny
2

Stok apache (1) dulu ditentukan sebelumnya hanya mendukung 250 koneksi bersamaan - jika Anda menginginkan lebih, ada satu file header untuk dimodifikasi untuk memungkinkan sesi yang lebih bersamaan. Saya tidak tahu apakah ini masih berlaku dengan Apache 2.

Selain itu, Anda perlu menambahkan opsi untuk memungkinkan lebih banyak deskriptor file terbuka untuk akun yang menjalankan Apache - sesuatu yang tidak ditunjukkan oleh komentar sebelumnya.

Perhatikan pengaturan pekerja Anda dan batas waktu keepalive seperti apa yang Anda miliki di dalam Apache itu sendiri, berapa banyak server cadangan yang Anda jalankan sekaligus, dan seberapa cepat proses ekstra ini terbunuh.

rasjani
sumber
1

Anda dapat mengurangi waktu yang dihabiskan dalam status TIME_WAIT (Tetapkan net.ipv4.tcp_fin_timeout). Anda bisa mengganti Apache dengan YAWS atau nginx atau yang serupa.

Pengorbanan lebih banyak koneksi umumnya melibatkan penggunaan memori, dan jika Anda memiliki proses forking, banyak proses anak yang membanjiri CPU Anda.

Devdas
sumber
1
tcp_fin_timeout bukan untuk mengatur kedaluwarsa TIME-WAIT, yang tidak dapat diubah di luar pembangunan kembali kernel, tetapi untuk FIN, seperti namanya.
Alexandr Kurilin
0

Jumlah absolut soket yang dapat dibuka pada satu alamat IP adalah 2 ^ 16 dan didefinisikan oleh TCP / UDP, bukan kernel.

Jason Tan
sumber
6
Bukan itu. Anda dapat membuka lebih banyak, karena port lokal tidak perlu unik selama alamat jarak jauh berbeda. Selain itu, kata OP per server, dan Anda dapat memiliki> 1 alamat per server.
MarkR