Мне нужно настроить сервер для обработки более одного миллиона открытых подключений к веб-сокетам (в идеале - двух миллионов).
Я использовал конфигурацию из этот Сообщение блога:
sysctl -w fs.file-max=12000500
sysctl -w fs.nr_open=20000500
ulimit -n 20000500
sysctl -w net.ipv4.tcp_mem='10000000 10000000 10000000'
sysctl -w net.ipv4.tcp_rmem='1024 4096 16384'
sysctl -w net.ipv4.tcp_wmem='1024 4096 16384'
sysctl -w net.core.rmem_max=16384
sysctl -w net.core.wmem_max=16384
Однако мое приложение перестает применять новые подключения после достижения 469219 подключений. Что я пропустил? Я действительно считаю, что в конфигурации ОС чего-то не хватает. Наше основное приложение написано на Java (с сервером Tomcat), но я также получил довольно похожие результаты с сервером NodeJS.
Мы используем Ubuntu с 16 ГБ оперативной памяти.
РЕДАКТИРОВАТЬ: на пике система использует около 12 ГБ из 14,7 ГБ.
UPD:
Итак, наконец, у меня есть рабочая станция на 32 ГБ. Проблема решена увеличением объема оперативной памяти. В настоящее время при использовании кучи Java 18 ГБ я могу обрабатывать 567 КБ соединений WS. Для больших чисел мне нужно больше клиентов :-)
Не обязательно ответ, но слишком большой, чтобы помещать комментарий.
tcp_mem (since Linux 2.4)
This is a vector of 3 integers: [low, pressure, high]. These bounds, measured in units of the system page size, are used by
TCP to track its memory usage. The defaults are calculated at boot time from the amount of available memory. (TCP can only
use low memory for this, which is limited to around 900 megabytes on 32-bit systems. 64-bit systems do not suffer this limi-
tation.)
low TCP doesnât regulate its memory allocation when the number of pages it has allocated globally is below this number.
pressure When the amount of memory allocated by TCP exceeds this number of pages, TCP moderates its memory consumption. This
memory pressure state is exited once the number of pages allocated falls below the low mark.
high The maximum number of pages, globally, that TCP will allocate. This value overrides any other limits imposed by the
kernel.
Обратите внимание на следующее:
Эти границы, измеренные в единицах измерения размер системной страницы
Установка этого значения на 10000000 10000000 10000000
указывает ядру использовать 39062 Мбайт памяти для TCP. Почти утроил то, что у вас есть.
Вторая проблема - это 3 значения TCP rmem
и wmem
вы устанавливаете определение минимума, значения по умолчанию и максимума. Учитывая, что ваша конфигурация tcp_mem заявляет, что вы никогда не переходите в режим «экономии памяти», я полагаю, что вы фактически выделяете где-то между 4-16 КБ на сокет.
Итак, если бы я был ядром и видел такие безумные настройки, я бы тоже мог вести себя не так предсказуемо.
Попробуйте уменьшить это значение до того, что вы действительно можете использовать, и повторите попытку.
Наконец, я отмечу, что вы живете в мире грез, если серьезно верите, что:
Даже при лучших обстоятельствах (при использовании набора epoll) 2 миллиона записей в наборе epoll - это дорого. Этого никогда не случится с рабочей моделью или моделью prefork.
Вам нужно распределять эту нагрузку более равномерно. Вам, вероятно, понадобятся еще 10 узлов, по крайней мере, чтобы получить что-то достойное того, что пользователь назвал бы услугой.