У меня Apache httpd (2.2.22) настроен как обратный прокси.
Есть ситуация, когда мне нужно отключить свой веб-сервер (получатель проксируемых запросов) на несколько миллисекунд. В это время веб-сервер не должен получать никаких запросов, но я также не хочу отклонять какие-либо запросы.
Я хотел бы каким-то образом заставить httpd задерживать все запросы на этот период времени. По шагам:
Фиксированная задержка также поможет, но, поскольку я не могу предвидеть фактическое время, в течение которого веб-сервер будет отключен (кроме того, что это будет меньше одной секунды), лучше подходит динамический подход.
Я смотрел, как mod_proxy или mod_balancer могут мне помочь, но не нашел очевидного решения.
Я буду рад любым указателям, которые вы мне дадите.
Редактировать:
Похоже, статического подхода достаточно. Некоторые полезные ресурсы:
Альтернативное решение:
Мы будем развертывать systemd на наши серверы. systemd решит мою проблему, потому что он может сохранять запросы на сокеты, закрытые с одной стороны. Это означает, что когда я останавливаю внутренний сервер на короткий период времени, все запросы будут помещены в очередь, пока я не запустил его снова и не подключился к сокету. Это я называю элегантным :)
В ProxyPass
Директива принимает множество параметров для настройки того, как будет обрабатываться соединение с внутренним сервером.
Среди этих параметров вас могут заинтересовать:
connectiontimeout <n>
: Количество секунд, в течение которых Apache ожидает завершения создания соединения с серверной частью.timeout <n>
: Количество секунд, в течение которых Apache ожидает данных, отправленных серверной частью или на нее.ttl <n>
: Время жизни для неактивных подключений и связанных записей пула подключений в секундах.Лучшим решением было бы иметь несколько внутренних серверов и балансировать нагрузку на члены и обнаруживать офлайн-серверы с помощью ping
параметр. Итак, когда вы перезагружаете бэкэнд-сервер, другой может взять на себя реле.
Вместо Apache вы можете использовать Iptables на своем веб-сервере, чтобы получить это следующим образом:
Поскольку брандмауэр незаметно разрывает новые соединения, обратный прокси будет продолжать повторно отправлять TCP-синхронизацию на веб-сервер. Установленные соединения не пострадают.
Если цикл завершится менее чем за одну секунду, новые клиенты увидят задержку (точно) в 1 секунду, равную задержке до первой повторной попытки SYN.
Пример конфигурации iptables (скажем, цепочка INPUT имеет пустую политику ACCEPT):
/sbin/iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 80 -j DROP
после перезапуска веб-сервера:
/sbin/iptables -F
Вы также можете применить политику к цепочке OUTPUT обратного прокси, но быстрая синхронизация действий может быть более сложной задачей.
Если он должен находиться в стазисе только на несколько миллисекунд, просто используйте плавный перезапуск Apache. У него уже есть эти свойства
Низкотехнологичный подход, похожий на предложение iptables, но полностью прозрачный для клиентов: просто остановите apache с помощью kill -stop
и перезапустите его с помощью kill -cont
. В зависимости от количества входящих пакетов ядро должно буферизовать все за это короткое время. Возможно даже эту буферизацию можно настроить.