Модуль Apache mod_proxy_ajp преждевременно отправляет трафик на запасной сервер - PullRequest
0 голосов
/ 20 сентября 2019

У нас есть пара веб-серверов Apache 2.4 (web02, web03), на которых mod_proxy_ajp разговаривает с парой серверов Tomcat 7.0.59 (app02, app03).

Сервер Tomcat на app03 является резервным сервером, который не должен получать трафик, если app02 не полностью отключен.

Конфигурация Apache на web02 и web03:

<Proxy balancer://ajp_cluster>
  BalancerMember ajp://app02:8009 route=worker1 ping=3 retry=60
  BalancerMember ajp://app03:8009 status=+R route=worker2 ping=3 retry=60
  ProxySet stickysession=JSESSIONID|jsessionid lbmethod=byrequests
</Proxy>

Конфигурация Tomcat для AJP в app02 и app03:

<Connector protocol="AJP/1.3" URIEncoding="UTF-8" port="8009" />

Мы видим проблемы, когда Apache начинает отправлять трафик на app03, который помечен какзапасной, даже если app02 все еще доступен, но, возможно, немного занят.

Журнал ошибок Apache SSL:

[Thu Sep 12 14:23:28.028162 2019] [proxy_ajp:error] [pid 24234:tid 140543375898368] (70007)The timeout specified has expired: [client 207.xx.xxx.7:1077] AH00897: cping/cpong failed to 10.160.160.47:8009 (app02)
[Thu Sep 12 14:23:28.028196 2019] [proxy_ajp:error] [pid 24234:tid 140543375898368] [client 207.xx.xxx.7:1077] AH00896: failed to make connection to backend: app02
[Thu Sep 12 14:23:28.098869 2019] [proxy_ajp:error] [pid 24135:tid 140543501776640] [client 207.xx.xxx.7:57809] AH01012: ajp_handle_cping_cpong: ajp_ilink_receive failed, referer: https://site.example.com/cart
[Thu Sep 12 14:23:28.098885 2019] [proxy_ajp:error] [pid 24135:tid 140543501776640] (70007)The timeout specified has expired: [client 207.xx.xxx.7:57809] AH00897: cping/cpong failed to 10.160.160.47:8009 (app02), referer: https://site.example.com/cart

В нашем Apache есть сотни таких сообщенийlogs.

Какие-либо предложения по настройке для установки Apache на app02, если он не полностью отключен?

1 Ответ

2 голосов
/ 23 сентября 2019

Вы испытываете истощение потока в коннекторе Tomcat, из-за чего httpd считает, что app02 находится в плохом состоянии, что, в некотором смысле, так.

Краткий ответ - переключите ваш коннектор Tomcat AJP для использования protocol="org.apache.coyote.ajp.AjpNioProtocol"

Длинный ответ, ну, скорее, длиннее.

mod_jk использует постоянные соединения между httpd и Tomcat.Исторический аргумент для этого - производительность.Это экономит время установления нового TCP-соединения для каждого запроса.Как правило, тестирование показывает, что этот аргумент не выполняется и что время, необходимое для установления нового TCP-соединения или выполнения CPING / CPONG для подтверждения того, что соединение допустимо (что необходимо сделать, если вы используете постоянные соединения), занимаетдостаточно близко в то же время.Тем не менее постоянные соединения являются стандартными с помощью mod_jk.

При использовании постоянных соединений mod_jk создает одно соединение на рабочий поток httpd и кэширует это соединение в рабочем потоке.

Соединение AJP по умолчанию в Tomcat 7.x это БИО разъем.Этот соединитель использует блокирующий ввод / вывод и требует одного потока на соединение.

Проблема возникает, когда в httpd настроено больше рабочих, чем в Tomcat.Изначально все ок.Когда работник httpd встречает первый запрос, который необходимо передать Tomcat, mod_jk создает постоянное соединение для этого работника httpd, и запрос обрабатывается.Последующие запросы, обрабатываемые этим работником httpd, которые необходимо передать Tomcat, будут использовать это кэшированное соединение.Запросы распределяются (эффективно) случайным образом среди работников httpd.Поскольку все больше работников httpd видят свой первый запрос, который необходимо передать Tomcat, mod_jk создает необходимое постоянное соединение для каждого работника.Вполне вероятно, что многие из подключений к Tomcat будут в основном простаивать.Время простоя будет зависеть от нагрузки на httpd и доли тех запросов, которые передаются в Tomcat.

Все хорошо, пока большему количеству работников httpd не потребуется создать соединение с Tomcat, в котором Tomcat имеет потоки.Помните, что для BIO-коннектора Tomcat AJP требуется поток для каждого соединения, поэтому maxThreads - это, по сути, максимальное количество соединений AJP, которое допускает Tomcat.В этот момент mod_jk не может создать запрос, и поэтому инициируется процесс аварийного переключения.

Существует два решения.Первый - тот, который я описал выше - это удалить один поток на ограничение соединения.Переключаясь на соединитель NIO AJP, Tomcat использует поток Poller для поддержки тысяч соединений, передавая только те, у которых есть данные, для обработки в поток для обработки.В этом случае ограничение для обработки Tomcat заключается в том, что maxThreads - это максимальное количество одновременных запросов, которые Tomcat может обработать в этом соединителе.

Второе решение заключается в отключении постоянных соединений.mod_jk создает соединение, использует его для одного запроса, а затем закрывает его.Это уменьшает количество соединений, которые требует mod_jk в любой точке между httpd и Tomcat.

Извините, выше приведен довольно большой текстовый слой.Я также освещал это в различных презентациях, включая , эту .

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...