Сначала подведем итог содержания статьи:
tcp_max_syn_backlog
、net.core.somaxconn
иlisten(fd, backlog)
изbacklog
Определяется минимумом из трех。net.core.somaxconn
иlisten(fd, backlog)
изbacklog
Минимальное значение из двух определяет。net.core.somaxconn
иtcp_max_syn_backlog
Параметры для добавления очередиразмер.somaxconn
Параметры для добавления очереди大小,и根据tcp_abort_on_overflow
Решение по параметрудавыброситьACKГарантированный возвратдаотправлятьRSTСумка给клиентконец。tcp_max_syn_backlog
:定义系统Может同час Потому что трехстороннее рукопожатие не завершеноиз Сколько позиций в очереди полусоединения резервирует соединение?。net.core.somaxconn
:обозначение Все розетки в системемониторочередьизмаксимальная длина。tcp_abort_on_overflow
:Решать Полное переполнение очереди соединенийчасиз Поведение(выброситьACKилиотправлятьRST)。netstat -ant
или ss -ant
:Посмотреть локальноизTCPстатус соединения, проверьте, является ли количество SYN_SENTiz ненормальным.sysctl net.core.somaxconn
:Проверятьинастраиватьsomaxconn
изценить。sysctl net.ipv4.tcp_max_syn_backlog
:ПроверятьTCP半连接очередьизмаксимальная длина。cat /proc/sys/net/ipv4/tcp_abort_on_overflow
:Проверятьtcp_abort_on_overflow
изкогда前ценить。netstat -s | grep "overflowed"
:Проверять Полное переполнение очереди соединенийизчастота。wrk — это инструмент тестирования производительности HTTP, написанный на языке C и разработанный пользователем GitHub wg/wrk. Он может выполнять нагрузочное тестирование на сервере, генерируя большое количество HTTP-запросов, и выводить результаты тестирования в режиме реального времени, включая ключевые показатели производительности, такие как частота запросов, скорость передачи и количество подключений. Первоначальная цель разработки wrk — предоставить простой и удобный в использовании инструмент для тестирования производительности, гарантируя при этом точность и надежность результатов тестирования.
Использовать wrk очень просто. Основной формат команды следующий:
wrk [options] http://host:port/path
Среди них [options] — необязательный параметр, а http://host:port/path — это URL-адрес, который необходимо протестировать. Вот некоторые часто используемые варианты:
-c, --connections
:настраиватьи发连接数。-t, --threads
:настраивать线程数。-d, --duration
:настраивать测试持续часмежду(Второй)。-D, --header
:添加自定义просить头。-H, --default-header
:настраивать默认просить头。-s, --script
:обозначениеLuaфайл сценария,Используется для настройки поведения запроса.Например, для стресс-тестирования веб-сервера используйте следующую команду:
wrk -c 100 -t 10 -d 60 http://example.com/
Эта команда будет моделировать 100 одновременных подключений, использовать 10 потоков и продолжать тестирование в течение 60 секунд.
Максимальное значение очереди полного соединения TCP зависит от минимального значения между somaxconn и backlog, которое равно min(somaxconn, backlog), где:
Соответствующий код ядра:
// https://github.com/torvalds/linux/blob/master/net/socket.c /* * Perform a listen. Basically, we allow the protocol to do anything * necessary for a listen, and if that works, we mark the socket as * ready for listening. */ int __sys_listen(int fd, int backlog) { struct socket *sock; int err, fput_needed; int somaxconn; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock) { somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn; // /proc/sys/net/core/somaxconn if ((unsigned int)backlog > somaxconn) backlog = somaxconn; // TCP Максимальная длина полной очереди подключений min(somaxconn, backlog) err = security_socket_listen(sock, backlog); if (!err) err = sock->ops->listen(sock, backlog); fput_light(sock->file, fput_needed); } return err; }
Просмотр команд для полного переполнения очереди подключений
ss
# -n Не разбирать Служить имя # -t Показать только tcp sockets # -l Показ монитора(СЛУШАТЬ)из sockets ss -lnt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 511 0.0.0.0:80 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 127.0.0.1:631 0.0.0.0:* LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 511 [::]:80 [::]:* LISTEN 0 128 [::]:22 [::]:* LISTEN 0 128 [::1]:631 [::]:*
Мы можем видеть из исходного кода ss
Получено по команде Recv-Q/Send-Q
В «СЛУШАЙТЕ статус» и «нет LISTEN Значения, выражаемые словом «статус», различны.
// https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_diag.c static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, void *_info) { struct tcp_info *info = _info; if (inet_sk_state_load(sk) == TCP_LISTEN) { // socket Статус да LISTEN час r->idiag_rqueue = READ_ONCE(sk->sk_ack_backlog); // Текущий размер очереди полного подключения r->idiag_wqueue = READ_ONCE(sk->sk_max_ack_backlog); // Максимальная длина полной очереди подключений } else if (sk->sk_type == SOCK_STREAM) { // socket Статус не да LISTEN час const struct tcp_sock *tp = tcp_sk(sk); r->idiag_rqueue = max_t(int, READ_ONCE(tp->rcv_nxt) - READ_ONCE(tp->copied_seq), 0); // Количество байтов, полученных, но не прочитанных приложением r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; // Количество отправленных байтов, но не получено подтверждение } if (info) tcp_get_info(sk, info); }
# -n Не разбирать Служить имя # -t Показать только tcp sockets # -l Показ монитора(СЛУШАТЬ)из sockets
Для сокетов в состоянии не-LISTEN
# -n Не разбирать Служить имя
# -t Показать только tcp sockets
Чтобы добиться очевидных экспериментальных результатов, мы модифицируем настройки системы с длинной очередью подключений.
Установите somaxconn на 8
1. Обновите файл /etc/sysctl.conf, который является файлом конфигурации параметров ядра.
а. Добавьте новую строку net.core.somaxconn=8.
2. Выполните sysctl -p, чтобы конфигурация вступила в силу.
sudo sysctl -p
net.core.somaxconn = 8
3. Проверьте файл /proc/sys/net/core/somaxconn и убедитесь, что somaxconn является обновленной версией 8.
cat /proc/sys/net/core/somaxconn
8
Перезагрузите сервер и подтвердите полный размер очереди подключений с помощью ss -lnt grep :8888.
ss -lnt | grep 8080
LISTEN 0 8 0.0.0.0:8080 0.0.0.0:*
Как видите, максимальная длина полной очереди ссылок теперь равна 64, и обновление прошло успешно.
Развертывание службы nginx
apt install nginx
Настроить мониторинг nginx
vim /etc/nginx/conf.d/bingo.conf
server {
listen 8080 default;
server_name localhost;
location / {
return 200 "bingo";
}
}
Изменить количество рабочих мест
vim /etc/nginx/nginx.conf
worker_processes 1;
relead nginx
nginx -s reload
Проводить постоянное стресс-тестирование
wrk -t 6 -c 30000 -d 60s http://127.0.0.1:8080/
Используйте команду ss, чтобы просмотреть текущую ситуацию с очередью полных подключений TCP:
Может看到когда前изTCPПолностью подключен к Понятно9больше максимальногоTCP全连接очередь,Как только оно превысит Понятно系统настраиватьизTCP最大全连接очередь,Служитьконец потеряет последующие входящие запросы,我们Можетделатьиспользоватьnetstat -s Посмотреть статистику
Вы можете нажать 514458 раз, чтобы указать, сколько раз была переполнена очередь подключений. Обратите внимание, что это накопительное значение.
Вы можете выполнять его каждые несколько секунд. Если это число продолжает увеличиваться, очередь подключений иногда должна быть заполнена.
Анализ посредством захвата пакетов
Вы можете увидеть много сообщений SYN + ACK. Это связано с тем, что вся очередь подключений заполнена, что заставляет Клиента думать, что соединение TCP-сокета с Сервером было успешно установлено, и Сервер продолжает думать, что последующая отправка данных не удалась. что TCP-соединение не установлено и продолжает отправлять SYN+ACK.
Процесс запроса можно увидеть следующим образом:
Server конец socket Соединение попадает в очередь полусоединения, и после получения Client конец ACK После этого должно было быть socket Соединения сохраняются в полной очереди соединений, но дальняя очередь подключений заполнена,так Server конец DROP Пришло время ACK просить.
Server конец всегда здесь RETRY отправлять SYN+ACK, потому что DROP Понятно client конециз ACK просьба, так что socket Соединение все еще находится в очереди полусоединения, ожидая Client конецотвечать ACK。
По умолчанию отправляется запрос DROP, когда полная очередь подключений заполнена. Вы можете настроить /proc/sys/net/ipv4/tcp_abort_on_overflow, чтобы сервер отправлял сообщение RST клиенту, когда полная очередь подключений заполнена.
cat /proc/sys/net/ipv4/tcp_abort_on_overflow
0
tcp_abort_on_overflow имеет два необязательных значения:
Установите для tcp_abort_on_overflow значение 1.
root@adming-virtual-machine:/mnt/hgfs# echo "1" > /proc/sys/net/ipv4/tcp_abort_on_overflowroot@adming-virtual-machine:/mnt/hgfs# cat /proc/sys/net/ipv4/tcp_abort_on_overflow1
Сделать запрос
wrk -t 6 -c 30000 -d 60s http://127.0.0.1:8080/
Вы можете видеть, что вся очередь подключений заполнена.
Благодаря захвату пакетов вы можете увидеть множество сообщений о сбросе.
Настройка по умолчанию:Обычно рекомендуетсяtcp_abort_on_overflow
установлен на0,Это помогает при скачках трафика.часподдерживать связьизстабильность。
Управление трафиком:когдаTCP全连接очередь因流量突增而溢出час,если Служитьустройствовыбросить ПонятноклиентконецизACKСумка,Клиентский конец подумает, что соединение не удалось установить.,тем самым запуская механизм повторной передачи。настраиватьtcp_abort_on_overflow
для0允许系统существоватьочередь有空междучас继续处理这些连接просить,без немедленного прекращения их действия.
статус соединения:Прямо сейчасделатьсуществовать Служитьустройствоконециз Полное переполнение очереди соединенияиз случае, если у клиента закончился статус соединенияужедаESTABLISHED,клиентконец进程仍然会尝试существовать已建立из Подключеноотправлятьпросить.потому что Служитьустройство没有отвечатьACK,клиентконец Буду продолжать отправлять повторнопросить.
Управление очередью:если Служитьустройство进程只давременночас Причина в занятостиaccept
очередь满,Затем, как только очередь TCP-соединения освободится,,Новое сообщение запроса (включая ACK) может заставить сервер успешно установить соединение.
Установите сцену:仅существовать确定TCP全连接очередь会长期处于溢出состояниечас,Только тогда следуетtcp_abort_on_overflow
установлен на1,Это может быстро уведомить клиента о том, что соединение не может быть установлено.,Избегайте растраты ресурсов.
Компромиссы:установлен на1Может迅速释放资源,Но некоторыми показателями успешности соединения можно пожертвовать. поэтому,Если нет явных проблем с производительностью,В противном случае сохранение настройки по умолчанию из0 обычно является лучшим выбором.
Увеличьте очередь полных соединений TCP:существовать系统确认да Полное переполнение соединения,Основная причина не обнаружена. Мы можем увеличить размер полной очереди подключений в соответствии с вычислительной мощностью системы.,Восстановить и смягчить влияние онлайн-сбоев на клиентов.