LINUX.ORG.RU
ФорумAdmin

Лимиты соединений

 , , ,


0

1

Что-то ограничивает кол-во соединений на tcp сокете, конкретно websocket, схема такова: client -> cloudflare -> nginx -> node

Где то затык. Доходит примерно до 200 соединений и начинают виснуть.

Пользователи таковы:
Nginx - www-data
node - gobot

/etc/security/limits.conf
root      hard    nofile      500000
root      soft    nofile      500000

www-data      hard    nofile      500000
www-data      soft    nofile      500000

gobot      hard    nofile      500000
gobot      soft    nofile      500000


/etc/sysctl.conf
fs.file-max = 999999
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 10000
net.core.netdev_budget = 600
net.netfilter.nf_conntrack_max=1048576
net.netfilter.nf_conntrack_tcp_loose = 0
net.ipv4.tcp_max_syn_backlog = 4096

/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 9999;
events {
   worker_connections 2000;
}




Вроде все лимиты прописал. Что ещё может быть?

ss -l | grep 8091 порт websocket

Recv-Q           Send-Q
76 511


Я как понимаю тут есть ожидающие соединения (76)?

★★★★

Посмотри, какие лимиты стоят по-умолчанию. Запусти под рутом.

ulimit -a (cм.картинку https://i.postimg.cc/157GKYB4/ulimit-a.jpg)

Ограничения, которые нужно убрать:

open files, max user processes и max locked memory

Приведи /etc/security/limits.conf к такому виду

*   soft    nproc   65000
*   hard    nproc   1000000
*   -    nofile  1048576
root - memlock unlimited

Число 1048576 захардкожено в ядре, чтоб поставить больше, нужно пересобирать ядро.

sword
()
Ответ на: комментарий от sword
su www-data --shell /bin/bash --command "ulimit -aH"
real-time non-blocking time  (microseconds, -R) unlimited
core file size              (blocks, -c) unlimited
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 0
file size                   (blocks, -f) unlimited
pending signals                     (-i) 127543
max locked memory           (kbytes, -l) 4091496
max memory size             (kbytes, -m) unlimited
open files                          (-n) 500000
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) unlimited
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) 127543
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited



нигде лимитов нет... Но соединения иногда висят по 5-10 сек.

gobot ★★★★
() автор топика

Два виртхоста на 1 сервере - обычный https второй на порту 8443. Оба проксируются на node, на два сервиса http и websocket. На обычном сервере соединения летают моментально, на втором c затыками проскакивают по 0.2...1...5...10 сек.! Че за хрень? Гении помогите пожалуйста, я уже не знаю в какие лимиты что упирается. Само приложение судя по логам запрос отрабатывает моментально 5-10MS, но nginx в логах показывает 1-10сек.

gobot ★★★★
() автор топика

Продолжаю исследование ))...

Заметил что если Recv-Q растет на порту node 8091, то идут затыки, на порту 8443 (nginx, который проксирует на 8091 порт) Recv-Q не растет

ss -l  | grep 8443
tcp   LISTEN 0 (Recv-Q)      511 (Send-Q)


ss -l  | grep 8091
tcp   LISTEN 74 (Recv-Q)      511 (Send-Q)



Recv-Q насколько я понял из чтения, это буфер который накапливает сокет и который ещё не прочитало приложение (не было recv). Почему оно не читает? Чего ждет? Проц вообще не нагружен ни капли, вроде читай да читай что мешает!

gobot ★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Я ни чем не уверен ) Но, судя по экспериментам, она отрабатывает запрос за 1-5ms, а nginx тот же запрос 1-5-10 сек. Это когда соединениями набьешь, если соединений нет то nginx и node быстро

Даже если выкинуть websocket из node, все равно nginx долго запрос обрабатывает

gobot ★★★★
() автор топика
Последнее исправление: gobot (всего исправлений: 1)
Ответ на: комментарий от gobot

Я бы начинал с простых вариантов. Заткнуть энджиникс сетевыми соединениями это прямо странно. А вот однопоточную ноду - почему нет. Просто нагрузи её отдельно. Может у тебя тормоза потому что энджиникс ждет от ноды соединения?

ya-betmen ★★★★★
()
Ответ на: комментарий от cobold

Проверил напрямую запросы к ноде напрямую через localhost,

ab -n 1000 -c 1000 http://127.0.0.1:8091
5.сек.

ab -n 1000 -c 1000 https://nginx:8443
16.сек.


Разница через прокси около 2 раз. Причем если напрямую к ноде, то
Recv-Q не растет, всегда 0, когда через nginx то растет (на одном и тоже же порту node 8091)

gobot ★★★★
() автор топика

Пробуй установить net.core.somaxconn = 300000 у тебя 65535. Весь sysctl.conf для высоконагруженной системы

net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
net.ipv4.tcp_syncookies = 0
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
vm.swappiness = 0
net.ipv4.tcp_fack = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_mem = 8388608 12582912 16777216
net.ipv4.udp_mem = 8388608 12582912 16777216
net.ipv4.udp_rmem_min = 16384
net.ipv4.udp_wmem_min = 16384
net.core.wmem_max = 8388608
net.core.rmem_max = 8388608
net.ipv4.tcp_rmem = 8192 87380 8388608
net.ipv4.tcp_wmem = 8192 87380 8388608
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 1
net.core.somaxconn = 300000
net.core.netdev_max_backlog = 8192
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_keepalive_time = 180
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_max_tw_buckets = 1000000
net.ipv4.ip_local_port_range = 1024 65535
net.nf_conntrack_max = 1000000
sword
()
Ответ на: комментарий от gobot

А ss что показывает? Была как-то проблема с тем что у ядра заканчивались свободные порты для клиентских соединений из-за того что была куча соединений в состоянии close wait или как-то так

cobold ★★★★★
()
Ответ на: комментарий от cobold

Однако http соединения блокируются, когда в коде вызываются симметричные вызовы, например

Object.values(cliens).filter().map().sort().reduce().sort().toArray()

Сервер встает КОЛОМ! Он не принимает на сокете ничего падла и ждет! Поэтому растет очередь (как я понимаю это и есть Recv-Q). Как же так?

gobot ★★★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Да не это понятно, я просто совсем забыл эти грабли гребаные с этими блокировками. По идее в какие то треды надо выделять сам принимающий сервер и логику, но хотя с другой стороны, примешь ты соединение и передаешь ее в другой поток, который опять же занят и будет оно так же висеть... Ладно это уже другая тема )

gobot ★★★★
() автор топика
Ответ на: комментарий от cobold

А что то я понять не могу, почему 1 сообщение в websocket может повешать весь сервер, если оно например будет перебирать масив секунду, то все остальные 1 000 000 клиентов будут ждать этого тормоза. Как же так? Это вообще нормально? Сами операции ввода вывода(обращение в бд) не блокируют.

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

если оно например будет перебирать масив секунду, то все остальные 1 000 000 клиентов будут ждать этого тормоза. Как же так? Это вообще нормально?

Блин, ты ж сам в предыдущем сообщении ответил про ноду. Асинхронность ноды это не многопоточность, и если твой скрипт перебирает какой-то массив, то в это время ничего больше не делается.

goingUp ★★★★★
()
Ответ на: комментарий от gobot

Нууу например запускать тяжелые запросы в отдельном потоке, но если у тебя реально лям запросов, то надо контролировать их количество. Или использовать message queue для этого и n процессов, которые будут выгребать очередь и выполнять запросы.

Вот допустим для пыха это делает nginx, там такой проблемы нет, но на каждый запрос чуть больше оверхеда.

goingUp ★★★★★
()
Последнее исправление: goingUp (всего исправлений: 1)
Ответ на: комментарий от goingUp

Все это сложно очень. Как таковых тяжелых нет, но сам факт, что такой конфуз может быть удручает.

Про пых мне кажется ты php-fpm имеешь ввиду? Но какое отношение это в websocket имеет?

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Но какое отношение это в websocket имеет?

Есть вебсокет серверы на пыхе же.

О, еще идея, запустить по одному серверу ноды на каждое ядро проца на разных портах, и сделать лоад балансинг между ними средствами nginx) Но память между ними не будет шариться)

goingUp ★★★★★
()
Последнее исправление: goingUp (всего исправлений: 3)
Ответ на: комментарий от gobot

Да дело не в маштрабации пока

Вот твой node сервер грузит процессорное ядро на 100% когда перебирает массив, так что уже дело в ней.

goingUp ★★★★★
()
Последнее исправление: goingUp (всего исправлений: 1)
Ответ на: комментарий от goingUp

А я кстати пока не пойму чего оно так грузится. В цикле 500 клиентов перебирает всего лишь, и складывает. Вообще современная парадигма процессов linux какая то глупая. То, что семеро ждут одного. Ну пусть этот один чудак пыхтит себе потихоньку, но зачем блокировать остальных. Понятно, что нужен тред отдельный, но с ними тоже проблем хватает.

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Да нормально там все с парадигмой процессов в линукс. Вот для php-fpm такой проблемы нет, потому что там так реализовано. А твой websocket сервер на ноде реализован так, что достигается большая легковесность, но есть проблема, что не грузится больше одного ядра. Вебсокет сервер на php может быть реализован также, с той же проблемой, это просто как пример, что архитектура может быть разная.

goingUp ★★★★★
()
Ответ на: комментарий от gobot

Ну просто пример, что все нормально с «парадигмой процессов linux». php-fpm спавнит n процессов и раскидывает запросы по ним. У тебя же один процесс ноды, который может грузить одно ядро.

goingUp ★★★★★
()
Ответ на: комментарий от gobot

А ты стало быть хотел бы чтобы ядро вместо тебя треды создавало? Ну типа вот перебираешь ты там свои 500 клиентов, как произошла до какое-то сетевое событие ядро прерывает этот потом и передает управление тому потоку, который сетевые события слушает? Бери голанг или ерланг и пили свою поделку

cobold ★★★★★
()
Ответ на: комментарий от cobold

Только не тред создавать, а разруливать ресурсами, делить их поровну, по братски. Каждая функция - поток. Между функциями делится процессор в пределах процесса. Это же так просто и очевидно.

gobot ★★★★
() автор топика
Последнее исправление: gobot (всего исправлений: 2)

Я так понимаю, проблема найдена?

Но непонятно одно, почему, если проблема в nodejs, возникает разница при обращении через nginx и напрямую на nodejs?

И задержка больше через прокси, а не напрямую?

usermod
()