В настоящее время я использую nginx для запросов обратного прокси от веб-клиентов, которые выполняют длительный опрос восходящего потока.
Поскольку мы проводим длительный опрос (в отличие от веб-сокетов), когда клиент подключается, он будет выполнять несколько последовательных HTTP-подключений к серверу, повторно устанавливая соединение каждый раз, когда сервер отправляет ему некоторые данные (или тайм-аут и повторно установление, если серверу нечего сказать в течение 10 секунд).
Я бы хотел ограничить количество одновременно работающих веб-клиентов. Поскольку клиенты постоянно отправляют новые HTTP-запросы вместо того, чтобы держать открытым один запрос, немного сложно подсчитать общее количество веб-клиентов (потому что это не то же самое, что общее количество одновременно подключенных HTTP-клиентов).
Метод, который я придумал, - это отслеживать HTTP-запросы по исходному IP-адресу и сохранять IP-адрес где-нибудь с TTL в 20 секунд. Если поступает запрос, IP-адрес которого не распознан, мы проверяем общее количество неистекших сохраненных IP-адресов; если это меньше максимального значения, мы пропускаем этот запрос. И если запрос приходит с IP-адресом, который мы можем найти в таблице поиска, срок действия которого еще не истек, то он также разрешен. IP-адреса всех разрешенных запросов добавляются в таблицу (если их не было раньше), а TTL снова обновляется до 20 секунд.
Я на самом деле собрал что-то, что корректно работало таким образом, используя nginx вместе с Модуль Redis 2.0 Nginx (и nginx lua модуль для упрощения условного ветвления), используя redis для хранения моих IP-адресов с TTL ( SETEX
команда), и проверка размера таблицы с помощью DBSIZE
команда.
Это сработало, но производительность была ужасной. nginx и redis в конечном итоге использовали большое количество ЦП, и машина могла обрабатывать только очень небольшое количество одновременных запросов.
Новый stick-table
и счетчики отслеживания, которые были добавлены в Haproxy в версии 1.5 (через комиссия от сбоя сервера) кажется, что они могут быть идеальными для реализации именно такого ограничения скорости, потому что таблица стикеров может отслеживать IP-адреса и автоматически удалять записи. Однако я не вижу простого способа получить общее количество неистекших записей в таблице стикеров, которое было бы необходимо для определения количества подключенных веб-клиентов.
Мне любопытно, есть ли у кого-нибудь предложения для nginx или haproxy или даже для чего-то еще, не упомянутого здесь, о чем я еще не подумал.
Удивительно, но сейчас нет ничего, что могло бы сообщить количество записей в таблице стикеров для использования с ACL, хотя, вероятно, это 10-строчный патч, который нужно добавить в haproxy 1.5, если это может помочь.
Если у вас получится сделать это самостоятельно, пришлите его мне, и я объединю его с основной веткой. В противном случае выкиньте меня из списка, чтобы я не забыл добавить это.