На максимальну кількість підключень впливають певні обмеження як на стороні клієнта, так і на сервері, хоча і дещо інакше.
На стороні клієнта:
збільшуйте діапазон порід ефермальних і зменшуйтеtcp_fin_timeout
Щоб дізнатись значення за замовчуванням:
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout
Діапазон ефермального порту визначає максимальну кількість вихідних сокетів, які хост може створити з певної IP-адреси. fin_timeout
Визначає мінімальний час ці розетки буде перебувати в TIME_WAIT
стані (непридатним для використання після того , як використовується один раз). Зазвичай типовими системами є:
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
Це в основному означає, що ваша система не може стабільно гарантувати більше, ніж (61000 - 32768) / 60 = 470
розетки в секунду. Якщо ви цим не задоволені, можете почати із збільшення рівня port_range
. Налаштування діапазону 15000 61000
досить поширене в наші дні. Ви можете додатково збільшити доступність, зменшивши fin_timeout
. Припустимо, що ви робите і те, і інше, вам слід побачити більше 1500 вихідних з'єднань за секунду.
Щоб змінити значення :
sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30
Сказане вище не слід тлумачити як фактори, що впливають на здатність системи здійснювати вихідні з'єднання в секунду. Але, скоріше, ці фактори впливають на здатність системи керувати одночасними з'єднаннями стійким чином протягом великих періодів "активності".
Значення Sysctl за замовчуванням у типовому вікні Linux для tcp_tw_recycle
& tcp_tw_reuse
буде
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0
Вони не дозволяють з'єднатись із "використаного" сокета (у стані очікування) і змушують сокети тривати весь time_wait
цикл. Рекомендую встановити:
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
Це дозволяє швидко перемкнути розетки в time_wait
стані та повторно використовувати їх. Але перш ніж зробити цю зміну, переконайтеся, що це не суперечить протоколам, які ви б використовували для програми, яка потребує цих сокетів. Не забудьте прочитати публікацію "Справляючись з TCP TIME-WAIT" від Вінсента Берната, щоб зрозуміти наслідки. Цей net.ipv4.tcp_tw_recycle
сервер досить проблематичний для публічних серверів, оскільки він не обробляє з'єднання двох різних комп’ютерів за одним і тим же NAT-пристроєм , що важко виявити і чекати, коли вас укусить. Зверніть увагу , що net.ipv4.tcp_tw_recycle
було видалено з Linux 4.12.
На стороні сервера:net.core.somaxconn
значення відіграє важливу роль. Він обмежує максимальну кількість запитів, що стоять у черзі на розетку прослуховування. Якщо ви впевнені у можливості свого серверного додатка, прискоріть його з 128 за замовчуванням на щось на зразок від 128 до 1024. Тепер ви можете скористатися цим збільшенням, змінивши змінну відсталого прослуховування у виклику прослуховування вашої програми на рівне або вище ціле число.
sysctl net.core.somaxconn=1024
txqueuelen
Параметр ваших Ethernet-карт також має грати роль. Значення за замовчуванням становлять 1000, тому підпишіть їх до 5000 і навіть більше, якщо ваша система може це впоратися.
ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local
Аналогічно підбиваємо значення для net.core.netdev_max_backlog
і net.ipv4.tcp_max_syn_backlog
. Їх значення за замовчуванням відповідно 1000 і 1024.
sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048
Тепер не забудьте запускати як клієнтські, так і серверні додатки, збільшуючи FD ulimts в оболонці.
Окрім перерахованого вище, ще одна популярна методика, яка використовується програмістами, - зменшити кількість викликів на запис tcp . Моє власне вподобання - використовувати буфер, в якому я відштовхую дані, які я хочу надіслати клієнтові, а потім у відповідних точках виписую буферизовані дані у фактичний сокет. Ця методика дозволяє використовувати великі пакети даних, зменшує фрагментацію, зменшує використання процесора як на землі користувача, так і на рівні ядра.