Подтвердить что ты не робот

Ошибка Bad Gateway 502 с Apache mod_proxy и Tomcat

Мы запускаем веб-приложение на Tomcat 6 и Apache mod_proxy 2.2.3. Увидев много таких ошибок:

Плохой шлюз! Прокси-сервер получил неверный ответ от восходящего сервера.

Прокси-сервер не смог обработать запрос GET/the/page.do.

Причина: Ошибка чтения с удаленного сервера

Если вы считаете, что это ошибка сервера, обратитесь к веб-мастеру.

Ошибка 502

В Tomcat есть много потоков, поэтому он не ограничен потоком. Мы подталкиваем 2400 пользователей через JMeter против приложения. Все ящики сидят внутри нашего брандмауэра в быстрой разгруженной сети, поэтому проблем с сетью не должно быть.

У кого-нибудь есть предложения по поводу того, что можно посмотреть или попробовать? Мы направляемся в tcpdump далее.

ОБНОВЛЕНИЕ 10/21/08: Все еще не понял этого. Увидеть только очень небольшое количество этих под нагрузкой. Ответы ниже не дают никаких магических ответов... пока.:)

4b9b3361

Ответ 1

Итак, отвечая на мой собственный вопрос. В конечном итоге мы определили, что мы наблюдаем ошибки 502 и 503 в балансировщике нагрузки из-за тайм-аутов Tomcat. В краткосрочной перспективе мы увеличили время ожидания. В долгосрочной перспективе мы исправили проблемы с приложением, которые вызывают таймауты в первую очередь. Почему таймауты Tomcat воспринимаются как ошибки 502 и 503 в балансировщике нагрузки, все еще немного загадочны.

Ответ 2

Чтобы добавить некоторые конкретные настройки, у меня была аналогичная настройка (с Apache 2.0.63 обратного проксирования на Tomcat 5.0.27).

Для определенных URL-адресов сервер Tomcat может занять около 20 минут, чтобы вернуть страницу.

В результате я изменил следующие параметры в файле конфигурации Apache, чтобы предотвратить его тайминги с его прокси-операцией (с большим коэффициентом переполнения в случае, если Tomcat занял больше времени, чтобы вернуть страницу):

Timeout 5400
ProxyTimeout 5400

Некоторый backgound

ProxyTimeout было недостаточно. Глядя на документацию для Timeout Я предполагаю (я не уверен), что это происходит потому, что, пока Apache ждет ответа от Tomcat, нет потока трафика между Apache и браузером (или любым другим клиентом http), и поэтому Apache закрывает соединение с браузером.

Я обнаружил, что если бы я оставил параметр Timeout по умолчанию (300 секунд), то если запрос прокси для Tomcat занял более 300 секунд, чтобы получить ответ, браузер отобразит страницу "502 Proxy Error". Я считаю, что это сообщение генерируется Apache, зная, что он действует как обратный прокси, прежде чем он закрывает соединение с браузером (это мое настоящее понимание - оно может быть ошибочным).

Страница прокси-сервера говорит:

Ошибка прокси-сервера

Прокси-сервер получил недопустимый ответ от восходящего сервера. прокси-сервер не смог обработать запросите GET.

Причина: Ошибка чтения с удаленного сервера

... что указывает на то, что параметр ProxyTimeout слишком короткий, в то время как исследование показывает, что время ожидания Apache Timeout (время ожидания между Apache и клиентом) также влияет на это.

Ответ 3

Вы можете использовать proxy-initial-not-pooled

См. Http://httpd.apache.org/docs/2.2/mod/mod_proxy_http.html:

Если эта переменная установлена, никакое пулевое соединение не будет использоваться повторно, если клиентское соединение является начальным соединением. Это позволяет избежать появления сообщения об ошибке "Прокси: ошибка чтения строки с удаленного сервера", вызванного условием состязания, когда внутренний сервер закрыл пул соединения после проверки соединения прокси-сервером и до того, как данные, отправленные прокси-сервером, достигли внутреннего сервера. Необходимо помнить, что установка этой переменной снижает производительность, особенно для клиентов HTTP/1.0.

У нас тоже была эта проблема. Мы исправили это, добавив

SetEnv proxy-nokeepalive 1
SetEnv proxy-initial-not-pooled 1

и keepAlive на всех серверах.

mod_proxy_http подходит для большинства сценариев, но мы запускаем его с большой нагрузкой, и у нас все еще есть некоторые проблемы с тайм-аутом, которые мы не понимаем.

Но посмотрите, соответствует ли приведенная выше директива вашим потребностям.

Ответ 4

Пример из Apache Conf:

#Default value is 2 minutes
**Timeout 600**
ProxyRequests off
ProxyPass /app balancer://MyApp stickysession=JSESSIONID lbmethod=bytraffic nofailover=On
ProxyPassReverse /app balancer://MyApp
ProxyTimeout 600
<Proxy balancer://MyApp>
    BalancerMember http://node1:8080/ route=node1 retry=1 max=25 timeout=600
    .........
</Proxy>

Ответ 5

Я предполагаю, что вы используете mod_proxy_http (или прокси-балансир).

Посмотрите в свои журналы tomcat (localhost.log или catalina.log). Я подозреваю, что вы видите исключение в своем веб-стеке, которое пузырится вверх и закрывает сокет, к которому подключен рабочий объект tomcat.

Ответ 6

вы должны решить эту проблему с помощью таймаута и параметра proxyTimeout, установленного на 600 секунд. Это помогло мне после битвы некоторое время.

Ответ 7

Вы можете избежать глобальных тайм-аутов или иметь виртуальные хосты, указав тайм-ауты прокси-сервера в директиве ProxyPass следующим образом:

ProxyPass /svc http://example.com/svc timeout=600
ProxyPassReverse /svc http://example.com/svc timeout=600

Обратите внимание на timeout=600 секунды.

Однако это не всегда работает, когда у вас есть балансировка нагрузки. В этом случае вы должны добавить таймауты в обоих местах (проверенных в Apache 2.2.31)

Пример балансировки нагрузки:

<Proxy "balancer://mycluster">
     BalancerMember "http://member1:8080/svc" timeout=600
     BalancerMember "http://member2:8080/svc" timeout=600
</Proxy> 

ProxyPass /svc "balancer://mycluster" timeout=600
ProxyPassReverse /svc "balancer://mycluster" timeout=600

Замечание: timeout=600 на ProxyPass не требовалось, когда Chrome был клиентом (я не знаю почему), но без этого таймаута на ProxyPass Internet Explorer (11) прерывает использование соединения reset сервером.

Моя теория такова:

ProxyPass тайм-аут используется между клиентом (браузером) и Apache.

BalancerMember тайм-аут используется между Apache и бэкэнд.

Для тех, кто использует Tomcat или другую поддержку, вы также можете обратить внимание на таймауты HTTP-коннектора.

Ответ 8

Скорее всего, вы должны увеличить параметр Timeout в apache conf (значение по умолчанию 120 секунд)

Ответ 9

Я знаю, что это не отвечает на этот вопрос, но я пришел сюда, потому что у меня была та же ошибка с сервером nodeJS. Я застрял надолго, пока не нашел решение. Мое решение просто добавляет косую черту или / в конце proxyreserve apache.

мой старый код:

ProxyPass / http://192.168.1.1:3001
ProxyPassReverse / http://192.168.1.1:3001

правильный код:

ProxyPass / http://192.168.1.1:3001/
ProxyPassReverse / http://192.168.1.1:3001/