Ошибка Bad Gateway 502 с Apache mod_proxy и Tomcat
Вопрос
Мы запускаем веб-приложение на Tomcat 6 и Apache mod_proxy 2.2.3. Видя много ошибок 502, как это:
Bad Gateway! Прокси-сервер получил неверный ответ от вышестоящего сервера.
Прокси-сервер не смог обработать запрос GET /the/page.do.
Причина: ошибка чтения с удаленного сервера
Если вы считаете, что это ошибка сервера, обратитесь к веб-мастеру.
Ошибка 502
Tomcat имеет множество потоков, поэтому он не ограничен потоками. Мы подталкиваем 2400 пользователей через JMeter к приложению. Все блоки находятся внутри нашего брандмауэра в быстро разряженной сети, поэтому проблем с сетью не должно быть. Р>
У кого-нибудь есть предложения, на что посмотреть или попробовать? Далее мы идем в tcpdump.
ОБНОВЛЕНИЕ 21.10.08: Все еще не понял это. Видя только очень небольшое количество этих под нагрузкой. Ответы ниже не дали никаких волшебных ответов ... пока. :) Р>
Решение 2
Итак, отвечая на мой вопрос здесь. В конечном итоге мы определили, что в балансировщике нагрузки наблюдаются ошибки 502 и 503 из-за истечения времени ожидания потоков Tomcat. В краткосрочной перспективе мы увеличили тайм-аут. В более долгосрочной перспективе мы исправили проблемы с приложениями, которые изначально вызывали тайм-ауты. Почему таймауты Tomcat воспринимаются как ошибки 502 и 503 на балансировщике нагрузки, все еще остается загадкой.
Другие советы
Чтобы добавить некоторые конкретные настройки, у меня была похожая настройка (с обратным прокси-сервером Apache 2.0.63 на Tomcat 5.0.27).
Для определенных URL-адресов серверу Tomcat может потребоваться около 20 минут для возврата страницы.
Я закончил тем, что изменил следующие параметры в файле конфигурации Apache, чтобы предотвратить тайм-аут его работы с прокси-сервером (с большим фактором переполнения в случае, если Tomcat потребовалось больше времени, чтобы вернуть страницу):
Timeout 5400
ProxyTimeout 5400
<Ч>
немного фона
Одного толькоProxyTimeout было недостаточно. Просматривая документацию для времени ожидания я догадываюсь (я не уверен), что это происходит потому, что в то время как Apache ожидает ответа от Tomcat, между Apache и браузером (или любым другим http-клиентом) не проходит трафик, и поэтому Apache закрывает соединение с браузер.
Я обнаружил, что если я оставлю настройку Тайм-аут по умолчанию (300 секунд), то если запрос прокси-сервера Tomcat займет больше 300 секунд, чтобы получить ответ, браузер отобразит «Ошибка 502 прокси-сервера». стр. Я считаю, что это сообщение генерируется Apache, зная, что он действует как обратный прокси-сервер, прежде чем он закрывает соединение с браузером (это мое текущее понимание - оно может быть ошибочным).
На странице ошибки прокси-сервера сказано:
Ошибка прокси-сервера
Прокси-сервер получил недействительный ответ от вышестоящего сервера. прокси-сервер не может обработать запрос GET.
Причина: ошибка чтения с удаленного сервера
... что говорит о том, что параметр ProxyTimeout слишком короткий, а исследование показывает, что параметр времени ожидания Apache (время ожидания между Apache и клиентом) также влияет на это.
Вы можете использовать прокси-начально-не-объединяли р>
См. 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 хорош в большинстве сценариев, но мы запускаем его с большой нагрузкой, и у нас все еще есть некоторые проблемы с тайм-аутом, которые мы не понимаем. Р>
Но посмотрите, соответствует ли приведенная выше директива вашим потребностям.
Пример из 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>
Я предполагаю, что вы используете mod_proxy_http (или прокси-балансировщик).
Посмотрите в своих журналах tomcat (localhost.log или catalina.log). Я подозреваю, что вы видите исключение в вашем веб-стеке, которое пузырится и закрывает сокет, к которому подключен рабочий tomcat.
вы сможете решить эту проблему, установив для параметра timeout и proxyTimeout значение 600 секунд. Это сработало для меня после битвы некоторое время.
Вы можете избежать глобальных тайм-аутов или необходимости использовать виртуальные хосты, указав тайм-ауты прокси в директиве 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) прерывает, говоря, что соединение сбрасывается сервером.
Моя теория такова:
Тайм-аут ProxyPass
используется между клиентом (браузером) и Apache.
BalancerMember
используется между Apache и бэкэндом.
Тем, кто использует Tomcat или другую поддержку, вы также можете обратить внимание на тайм-ауты коннектора HTTP.
Скорее всего, вам нужно увеличить параметр Timeout в apache conf (значение по умолчанию 120 секунд)
Я знаю, что это не отвечает на этот вопрос, но я пришел сюда, потому что у меня была та же ошибка с сервером 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/