Що обмежує максимальну кількість підключень на сервері Linux?


89

Який параметр ядра чи інші параметри контролюють максимальну кількість сокетів TCP, які можна відкрити на сервері Linux? Які компроміси дозволяють отримати більше з'єднань?

Я помітив, під час завантаження тестування сервера Apache з ab, що досить легко максимізувати відкриті з'єднання на сервері. Якщо ви вимкнете опцію ab's -k, яка дозволяє повторно використовувати з'єднання, і надіслати більше 10 000 запитів, то Apache обслуговує перші 11 000 або більше запитів, а потім зупиняється на 60 секунд. Погляд виходу netstat показує 11000 з'єднань у стані TIME_WAIT. Мабуть, це нормально. З'єднання залишаються відкритими за замовчуванням 60 секунд, навіть після того, як клієнт зробив з ними з міркувань надійності TCP .

Здається, це був би простий спосіб зробити сервер DoS, і мені цікаво, що це за звичайні налаштування та заходи безпеки.

Ось мій тестовий результат:

# 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

Ось команда netstat, яку я запускаю під час тесту:

 # 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

Відповіді:


64

Я нарешті -то знайшов установку , яка була дійсно обмежує кількість з'єднань: net.ipv4.netfilter.ip_conntrack_max. Це було встановлено на 11 776, і все, що я встановив, це кількість запитів, які я можу подати в своєму тесті, перш ніж чекати tcp_fin_timeoutсекунд, щоб отримати більше з'єднань. У conntrackтаблиці використовується те, що ядро ​​використовує для відстеження стану з'єднань, тож після його заповнення ядро ​​починає скидати пакети та друкує це у журналі:

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

Наступним кроком було отримання ядра для переробки всіх цих з'єднань у TIME_WAITстані, а не відкидання пакетів. Я можу зробити так, щоб увімкнути tcp_tw_recycleабо збільшити ip_conntrack_maxкількість локальних портів, доступних для з'єднань ip_local_port_range. Я думаю, що коли ядро ​​не в локальних портах, воно починає переробляти з'єднання. Для цього використовується більше з'єднань для відстеження пам'яті, але це здається кращим рішенням, ніж включення, tcp_tw_recycleоскільки документи означають, що це небезпечно.

З цією конфігурацією я можу запускати ab весь день і ніколи не закінчувати з'єднання:

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

tcp_max_orphansУстановка не робить ніякого впливу на моїх тестах , і я не знаю , чому. Я б подумав, що це закриє зв'язки в TIME_WAITштаті, коли їх було 8192, але це не для мене.


3
Де ми налаштовуємо ці парами?
Codevalley

2
@Codevalley Це може залежати від системи, але на сервері Ubuntu вони переходять у /etc/sysctl.conf
Ben Williams

24

Ви дуже хочете подивитися, що / файлова система / proc може запропонувати вам у цьому плані.

На цій останній сторінці ви можете виявити наступне, що може вас зацікавити:

  • / proc / sys / net / ipv4 / tcp_max_orphans , який контролює максимальну кількість розеток, утримуваних системою, не прикріпленими до чогось. Підвищення цього може зайняти стільки, як 64 кбайт пам'яті, що не можна замінити, на розетку сиріт .
  • / proc / sys / net / ipv4 / tcp_orphan_retries , який контролює кількість повторних спроб до того, як сокет осиротеє та закриється. На цій сторінці є певна примітка про веб-сервери, які безпосередньо вас цікавлять ...

tcp_max_orphans цікаво, але здається, що це не працює. Коли я намагаюся виміряти осиротілих розеток під час свого тесту, я бачу їх 11 651, тоді як tcp_max_orphans - 8 092. # netstat --inet -p | grep "localhost: www" | sed -e 's / \ + / / g' | вирізати -d '' -f 1-4,6-7 | сортувати | uniq -c 11651 tcp 0 0 localhost: www TIME_WAIT -
Бен Вільямс

Подивіться на налаштування tcp_orphan_retries - ідея в тому, що розетки швидше "стикаються" ...
Avery Payne

Пропозиція @Jauder Ho + tcp_orphan_retries звучить як потенційна виграш для вашої ситуації.
Avery Payne

3

Я не думаю, що існує можливість налаштувати це безпосередньо. Це підпадає під категорію настройки TCP / IP. Щоб дізнатися, що ви можете настроїти, спробуйте "man 7 tcp". Для їх встановлення використовується sysctl ("людина 8 sysctl"). 'sysctl -a | grep tcp 'покаже вам більшість того, що ви можете настроїти, але я не впевнений, чи покаже це все. Крім того, якщо це не змінилося, розетки TCP / IP відкриваються схожими на дескриптори файлів. Тож цей і наступний розділ у цьому посиланні можуть бути тим, що ви шукаєте.


2

Спробуйте встановити наступне, а також встановити tcp_fin_timeout. Це має швидше закрити TIME_WAIT.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

Обережно тут! Пережив нелегкий шлях. "Це може спричинити випадання кадрів з балансуванням навантаження та NAT. Використовуйте це лише для сервера, який спілкується лише через вашу локальну мережу." - wiki.archlinux.org/index.php/Sysctl
Хенк

@Henk Я думаю, tcp_tw_recycleщо це потенційно небезпечно. tcp_tw_reuseє більш безпечним, і я не бачу жодної причини використовувати їх одночасно.
Владислав Раструсний

2

Фондовий апарат (1) використовувався заздалегідь, щоб підтримувати лише 250 одночасних з'єднань - якщо ви хочете більше, був один файл заголовка, який можна змінити, щоб дозволити більше одночасних сеансів. Я не знаю, чи це все ще вірно з Apache 2.

Крім того, потрібно додати параметр, щоб дозволити завантаження більш відкритих дескрипторів файлів для облікового запису, на якому працює Apache - те, на що попередні коментарі не вказували.

Зверніть увагу на налаштування вашого працівника та які тривалість часу очікування у вас є в самому Apache, скільки запасних серверів, які ви працюєте одразу, і як швидко ці додаткові процеси вбиваються.


1

Ви можете скоротити час, витрачений у стані TIME_WAIT (Встановити net.ipv4.tcp_fin_timeout). Ви можете замінити Apache на YAWS або nginx або щось подібне.

Компроміси більшої кількості підключень зазвичай передбачають використання пам’яті, а якщо у вас процес розгортання, багато дочірніх процесів, які переповнюють ваш процесор.


1
tcp_fin_timeout призначений не для встановлення терміну закінчення TIME-WAIT, який не змінюється за межами відновлення ядра, а для FIN, як вказує назва.
Олександр Курилін

0

Абсолютна кількість розеток, які можна відкрити на одній IP-адресі, дорівнює 2 ^ 16 і визначається TCP / UDP, а не ядром.


6
Ні, це не так. Ви можете відкрити більше, оскільки локальний порт не повинен бути унікальним, якщо віддалені адреси відрізняються. Більше того, ОП сказав на один сервер, і ви можете мати> 1 адресу на сервері.
MarkR

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.