Проблемы с Apache в тесте производительности с mod_reqtimeout

У нас есть 2 веб-сервера Apache за балансировщиком нагрузки, которые подключены к 2 (JBoss) серверам приложений через мод ajp.

К этим веб-серверам мобильные устройства подключаются через REST API.

В нашем тесте производительности мы довольно быстро столкнулись с множеством NonHttpResponse: ошибок, которые мы определили как происходящие из mod_reqtimeout:

[Mon Mar 16 14:42:49.324705 2015] [reqtimeout:info] [pid 27914:tid 140628428449536] [client 1.2.3.4:48280] AH01382: Request header read timeout

... который настроен следующим образом:

<IfModule reqtimeout_module>
    RequestReadTimeout header=10-20,minrate=500
    RequestReadTimeout body=10,minrate=500
</IfModule>

Я смог избавиться от этих ошибок, увеличив эти значения до

RequestReadTimeout header=20-60,minrate=100

Но это не может быть решением, поскольку с несколькими другими пользователями одновременно проблема возникла снова (существует требование обслужить 300 одновременных пользователей - 100 работали вполне нормально, с 300 у нас было более 10000 из этих тайм-аутов чтения заголовка запроса ошибки). Я подозреваю, что это взаимодействие apaches KeepAlive, нашей конфигурации mod_ajp и mod_reqtimeout, которое приводит mod_reqtimeout к выводу, что идет медленная атака (на многие открытые соединения, которые ничего не делают), и я прошу вашей помощи в настройке этих параметров.

Дополнительной проблемой является межсетевой экран между веб-сервером и сервером приложений, который, как я подозреваю, уничтожает открытые простаивающие соединения. Я прочитал о полной деактивации KeepAlive, чтобы решить эту проблему, но, как я уже сказал, все наши клиенты являются мобильными устройствами, так что это, вероятно, не вариант (?).

Вот другие конфиги (части):

workers.properties:

worker.list=server
worker.maintain=60

worker.server.type=ajp13
worker.server.host=server
worker.server.port=15869
worker.server.socket_keepalive=True
worker.server.connection_pool_timeout=600
worker.server.ping_mode=A
worker.server.connection_ping_interval=60

mod_prefork:

<IfModule prefork.c>
    StartServers         5
    MinSpareServers      5
    MaxSpareServers     10
    #MaxClients         256
    MaxClients         300
    MaxRequestsPerChild  0
</IfModule>

mainserver.conf:

Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

ssl.conf (мобильные устройства подключаются через ssl):

Timeout 1200
KeepAlive On
MaxKeepAliveRequests 0
KeepAliveTimeout 10

1 ответ

Необычно, что вы используете MPM "prefork" в том, что, по-видимому, является по существу обратным прокси-сервером, гибридный "рабочий" MPM обладает лучшей масштабируемостью, но это не проблема.

Снижение DoS обычно лучше всего обрабатывается (если не вашим провайдером) на внешнем устройстве, которое завершает клиентские запросы, по вашему описанию это балансировщик нагрузки, а не Apache. Любой компетентный балансировщик нагрузки будет знать HTTP (то есть "Уровень 7"), это, вероятно, приведет к буферизации HTTP-запросов. Это также применимо, если балансировщик нагрузки завершает HTTPS, но в меньшей степени, если балансировщик нагрузки просто ретранслирует HTTPS-соединения (поскольку он не может видеть HTTP-запросы для их буферизации). Это также не применимо, если ваш балансировщик нагрузки является простым "балансировщиком нагрузки типа NAT уровня 3/4".

Что касается возможной причины тайм-аутов:

  • ваш экземпляр SSL KeepAliveTimeout такой же, как RequestReadTimeout Тайм-аут чтения заголовка, возможно, есть гонка, в которой тайм-аут keepalive достигается в середине входящего клиентского запроса / заголовков. Если я пытаюсь воспроизвести это, в дополнение к ошибкам AH01382 я также получаю AH01991 (сбой чтения входного фильтра SSL) и AH00567 (сбой запроса: ошибка чтения заголовков). Это не может объяснить все проблемы, хотя.
  • неправильно сформированные клиентские запросы, не редкость в прошлом (например, дополнительные CR/LF после POST, неполные запросы при повторных попытках после ошибки). Я не знаю ничего текущего, хотя, это зависит от вашей клиентской базы и, что более важно, от их подключения.
  • может быть ошибка, похожая на эту недавнюю ошибку, которая приводила к ложным тайм-аутам с "событием" MPM.

Чтобы воспроизвести таймауты:

 $ openssl s_client -connect myhost:443
 GET / HTTP/1.1
 Host: myhost.whatever.com 

 [server reply goes here]
 GET / HTTP/1.1
 Host:

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

Может помочь уменьшение KeepAliveTimeout (по умолчанию 5 секунд). Обратите внимание, что KeepAliveTimeout - это время для получения полного запроса. Я думаю, что следующий шаг может быть mod_log_forensic,

Что касается подключений к бэк-энду через AJP, используете ли вы "ping" на ApacheBalancer конфигурация? Если я правильно понимаю вашу систему, указанная вами конфигурация Tomcat не будет применяться к соединениям с Apache httpd до Tomcat. Смотрите варианты здесь.

                          /-> apache httpd + ajp -\            /-> tomcat/jboss
client -> load-balancer  <                         > firewall <
                          \-> apache httpd + ajp -/            \-> tomcat/jboss
Другие вопросы по тегам