Как уменьшить количество сокетов в TIME_WAIT?

36

Ubuntu Server 10.04.1 x86

У меня есть машина с HTTP-сервисом FCGI за nginx, который обслуживает множество небольших HTTP-запросов для множества разных клиентов. (Около 230 запросов в секунду в часы пик, средний размер ответа с заголовками составляет 650 байтов, несколько миллионов разных клиентов в день.)

В результате у меня есть много сокетов, висящих в TIME_WAIT (график захвачен с настройками TCP ниже):

ВРЕМЯ ЖДЕТ

Я хотел бы уменьшить количество розеток.

Что я могу сделать кроме этого?

$ cat / proc / sys / net / ipv4 / tcp_fin_timeout
1
$ cat / proc / sys / net / ipv4 / tcp_tw_recycle
1
$ cat / proc / sys / net / ipv4 / tcp_tw_reuse
1

Обновление: некоторые подробности о фактической схеме обслуживания на машине:

клиент ----- TCP-сокет -> nginx (обратный прокси-сервер балансировки нагрузки) 
       ----- TCP-сокет -> nginx (рабочий) 
       --domain-socket -> fcgi-software
                          --single-persistent-TCP-socket -> Redis
                          --single-persistent-TCP-socket -> MySQL (другой компьютер)

Я, вероятно, должен также переключить балансировщик нагрузки -> подключение к рабочему сокету на доменные сокеты, но проблема с сокетами TIME_WAIT останется - я планирую добавить второго рабочего на отдельной машине в ближайшее время. Не сможет использовать доменные сокеты в этом случае.

Александр Гладыш
источник
Кажется, что Мунин бессовестно лжет. Смотрите комментарии к ответу Кайла. Глядя на это сейчас.
Александр Гладыш
1
Создан вопрос о Мунине
Александр Гладыш
Теперь похоже, что Мунин не лжет, а скорее смотрит на неправильный сюжет ...
Александр Гладыш

Ответы:

28

Одна вещь, которую вы должны сделать, чтобы начать это исправить net.ipv4.tcp_fin_timeout=1. Это путь к низкому уровню, вы, вероятно, не должны брать намного меньше 30.

Так как это позади nginx. Означает ли это, что nginx действует как обратный прокси-сервер? Если это так, то ваши подключения в два раза (один к клиенту, один к вашим веб-серверам). Вы знаете, к какому концу эти гнезда принадлежат?

Обновление:
fin_timeout - это то, как долго они остаются в FIN-WAIT-2 (из networking/ip-sysctl.txtдокументации ядра):

tcp_fin_timeout - INTEGER
        Time to hold socket in state FIN-WAIT-2, if it was closed
        by our side. Peer can be broken and never close its side,
        or even died unexpectedly. Default value is 60sec.
        Usual value used in 2.2 was 180 seconds, you may restore
        it, but remember that if your machine is even underloaded WEB server,
        you risk to overflow memory with kilotons of dead sockets,
        FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
        because they eat maximum 1.5K of memory, but they tend
        to live longer. Cf. tcp_max_orphans.

Я думаю, что вы, возможно, просто должны позволить Linux сохранить номер сокета TIME_WAIT по сравнению с тем, что на них похоже, возможно, с ограничением 32 КБ, и именно здесь Linux перерабатывает их. Это 32k упоминается в этой ссылке :

Кроме того, я нахожу путаницу / proc / sys / net / ipv4 / tcp_max_tw_buckets. Хотя по умолчанию установлено значение 180000, я вижу сбой TCP, когда в моей системе установлены 32K сокеты TIME_WAIT, независимо от макс. Двух сегментов.

Эта ссылка также предполагает, что состояние TIME_WAIT составляет 60 секунд и не может быть настроено через proc.

Случайный интересный факт:
вы можете увидеть таймеры на тайм-ауте с netstat для каждого сокета сnetstat -on | grep TIME_WAIT | less

Повторное использование против повторного использования:
это довольно интересно, оно выглядит как повторное использование, позволяет повторно использовать сокеты time_Wait, а повторное использование переводит его в режим TURBO:

tcp_tw_recycle - BOOLEAN
        Enable fast recycling TIME-WAIT sockets. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

tcp_tw_reuse - BOOLEAN
        Allow to reuse TIME-WAIT sockets for new connections when it is
        safe from protocol viewpoint. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

Я бы не рекомендовал использовать net.ipv4.tcp_tw_recycle, так как это вызывает проблемы с клиентами NAT .

Может быть, вы могли бы попробовать не включать оба из них и посмотреть, какой эффект это имеет (попробуйте по одному и посмотрите, как они работают самостоятельно)? Я бы использовал netstat -n | grep TIME_WAIT | wc -lдля более быстрой обратной связи, чем Munin.

Кайл Брандт
источник
1
@Kyle: какое значение net.ipv4.tcp_fin_timeoutвы бы порекомендовали?
Александр Гладыш
1
@Kyle: клиент --TCP-сокет -> nginx (обратный прокси-сервер балансировки нагрузки) --TCP-сокет -> nginx (рабочий) --домен-сокет -> fcgi-software
Александр Гладыш
2
Я бы сказал 30или, может быть 20. Попробуйте и посмотрите. У вас большая нагрузка, поэтому смысл TIME_WAIT имеет смысл.
Кайл Брандт
1
@Kyle: извините за глупый вопрос (к сожалению, я пока нахожусь на уровне культового груза), но что именно мне следует ожидать, когда я перейду net.ipv4.tcp_fin_timeoutс 1на 20?
Александр Гладыш
4
О, вот хороший лайнер netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c. Итак, @Alex, если Munin не нравится, возможно, рассмотрите, как он отслеживает эту статистику. Возможно, единственная проблема заключается в том, что Мунин дает вам плохие данные :-)
Кайл Брандт
1

tcp_tw_reuse относительно безопасен, поскольку позволяет повторно использовать соединения TIME_WAIT.

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

Эндрю Пэйт
источник