DmitryKoterov
@DmitryKoterov

Отлов дисконнекта клиента на стороне сервера?

Например, клиент посылает SQL-запрос (в PostgreSQL), сервер шлет ответ (может быть длинным), и в середине клиентский процесс вдруг внезапно умирает (например, по 9-му сигналу — возьмем для простоты).


Вопросы:

1. Как скоро сервер узнает об этом и перестанет ждать (т.е. как скоро PostgreSQL вернет процесс, обрабатывающий данное соединение, в пул готовых к новой работе)?

2. Как называется этот механизм, т.е. где о нем можно почитать?

3. Где настраивается эта задержка в Линуксе (если вообще она настраивается)?


Я просто подозреваю, что сервер может иногда узнавать о внезапном дисконнекте клиента минуты через 2-3 только. В итоге свободные процессы могут успеть закончиться, если вдруг происходит массовый мор клиентов.
  • Вопрос задан
  • 4172 просмотра
Пригласить эксперта
Ответы на вопрос 3
DmZ
@DmZ
Существует несколько ситуаций:
  • Если проблем в сети нет, то отвалившийся клиент «закроет» порт и сервер получит RST на свои пакеты, т.е. сервер «увидит» падение коннекта практически сразу.
  • Если существуют проблемы в сети, когда ответ от клиента не приходит, то есть параметры, которые отвечают за таймауты (выставляются через sysctl):
    tcp_retries1
    Целочисленная переменная tcp_retries1 определяет число неудачных попыток, после которого должна быть передана информация на сетевой уровень. В соответствии с RFC минимальное значение составляет 3 (по умолчанию установлено именно это значение), что соответствует периоду приблизительно от 3 секунд до 8 минут в зависимости от значения тайм-аута повторной передачи RTO (Retransmission time-out).

    tcp_retries2
    Целочисленная переменная tcp_retries2 определяет число неудачных попыток, после которого существующее соединение уничтожается. В соответствии с RFC 1122 тайм-аут должен быть больше 100 секунд. Такое значение слишком мало и по умолчания установлено число попыток 15, соответствующее тайм-ауту приблизительно от 13 до 30 минут в зависимости от RTO.

Все параметры описаны в документации к исходинкам ядра (Documentation/networking/ip-sysctl.txt)

Также эти параметры влияют на все TCP соединения данного сервера. Если нужно «тюнить» для конкретного своего приложения, то можно использовать параметр TCP_USER_TIMEOUT для tcp-сокета. Указывает время в миллисекундах ожидания подтверждения (ACK) данных. Параметр появился в 2.6.37.
Для более ранних ядер можно мониторить исходящую очередь на сокете, и если она не уменьшается какое-то время — значит что-то случилось.
Ответ написан
Комментировать
TheHorse
@TheHorse
На сколько я понимаю, на сервере произойдет ошибка «Connection reset by peer» (WSAECONNRESET в винде), почти моментально.

P. S. это не ответ, но надеюсь поможет в его поисках.
Ответ написан
alekciy
@alekciy
Вёбных дел мастер
1.
а) На уровне TCP:
Клиентский процесс умер, но хост клиента жив, значит TCP стек клиента в ответ на данные идущие с сервера отправит FIN. TCP сервера получит его, пошлет в ответ ACK и из ESTABLISHED перейдет в CLOSE_WAIT. После того как рабочий процесс сервера сделает close TCP стек сервера пошлет FIN и перейдет в LAST_ACK дожидаясь ACK от TCP клиента. Получив его перейдет в CLOSED.

Тут у нас длительность этого процесса зависит от того, на сколько быстро бегают у нас пакеты между хостами. Учитывая размеры, то как правило быстрее, менее секунды.

б) На уровне приложения:
Не знаю, чем пишет PostgreSQL в сокет, но в любом случае при попытке записи в сокет который перешел в CLOSE_WAIT рабочий процесс получит ошибку. write по идее должен завершиться с ошибкой EPIPE, после чего рабочий процесс должно сделать close, хотя может завершится и без этого, ядро фоном это сделает само. В первом приближении все должно происходить быстро и без задержек.

P.S. Описания добавленные в уточнении вопрос противоречат первоначальной формулировке вопроса. Не полученный отлуп к клиента это проблемы с сетью или хостом клиента, но в случае умирая процесса клиента TCP стек клиента по прежнему работает и он берет на себя функции уведомления хоста сервера об ошибке поэтому все происходит достаточно быстро.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы