Назад | Перейти на главную страницу

httpd: как динамически отложить пересылку запроса на прокси?

У меня Apache httpd (2.2.22) настроен как обратный прокси.

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

Я хотел бы каким-то образом заставить httpd задерживать все запросы на этот период времени. По шагам:

  1. скажите httpd отложить все запросы до дальнейшего уведомления
  2. остановить веб-сервер
  3. запустить веб-сервер
  4. продолжить пересылку запросов с httpd

Фиксированная задержка также поможет, но, поскольку я не могу предвидеть фактическое время, в течение которого веб-сервер будет отключен (кроме того, что это будет меньше одной секунды), лучше подходит динамический подход.

Я смотрел, как mod_proxy или mod_balancer могут мне помочь, но не нашел очевидного решения.

Я буду рад любым указателям, которые вы мне дадите.

Редактировать:

Похоже, статического подхода достаточно. Некоторые полезные ресурсы:

Альтернативное решение:

Мы будем развертывать systemd на наши серверы. systemd решит мою проблему, потому что он может сохранять запросы на сокеты, закрытые с одной стороны. Это означает, что когда я останавливаю внутренний сервер на короткий период времени, все запросы будут помещены в очередь, пока я не запустил его снова и не подключился к сокету. Это я называю элегантным :)

В ProxyPass Директива принимает множество параметров для настройки того, как будет обрабатываться соединение с внутренним сервером.

Среди этих параметров вас могут заинтересовать:

  • connectiontimeout <n>: Количество секунд, в течение которых Apache ожидает завершения создания соединения с серверной частью.
  • timeout <n>: Количество секунд, в течение которых Apache ожидает данных, отправленных серверной частью или на нее.
  • ttl <n>: Время жизни для неактивных подключений и связанных записей пула подключений в секундах.

Лучшим решением было бы иметь несколько внутренних серверов и балансировать нагрузку на члены и обнаруживать офлайн-серверы с помощью pingпараметр. Итак, когда вы перезагружаете бэкэнд-сервер, другой может взять на себя реле.

Вместо Apache вы можете использовать Iptables на своем веб-сервере, чтобы получить это следующим образом:

  1. сбросить новые подключения (tcp-SYN) к веб-серверу
  2. перезапустить веб-сервер
  3. повторно принять все подключения

Поскольку брандмауэр незаметно разрывает новые соединения, обратный прокси будет продолжать повторно отправлять 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. В зависимости от количества входящих пакетов ядро ​​должно буферизовать все за это короткое время. Возможно даже эту буферизацию можно настроить.