DmitryKoterov
@DmitryKoterov

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

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


Вопросы:

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

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

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


Я просто подозреваю, что сервер может иногда узнавать о внезапном дисконнекте клиента минуты через 2-3 только. В итоге свободные процессы могут успеть закончиться, если вдруг происходит массовый мор клиентов.
  • Вопрос задан
  • 4107 просмотров
Пригласить эксперта
Ответы на вопрос 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 стек клиента по прежнему работает и он берет на себя функции уведомления хоста сервера об ошибке поэтому все происходит достаточно быстро.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы