it-swarm.com.ru

504 ошибки из Elastic Load Balancer с использованием Tomcat

У меня есть приложение, работающее на нескольких экземплярах EC2 и обслуживаемое Apache Tomcat. Я установил AWS Elastic Load Balancer перед приложением, и все в основном работает, как и ожидалось. Тем не менее, я иногда получаю случайную ошибку тайм-аута 504 от ELB. Похоже, это не связано с нагрузкой, поскольку я видел ошибки при небольшой и большой нагрузке. Кроме того, это, кажется, не происходит ни в какой регулярной модели или ситуации.

Ранее в моем тестировании я получал 504 ошибки, потому что моему приложению требовалось больше времени, чем 60-секундный тайм-аут по умолчанию на ELB. Я решил это, увеличив тайм-аут ELB до уровня, необходимого для моего приложения. Однако те 504 ошибки, которые я получаю сейчас, происходят очень быстро. Так, например, одна ошибка, которую я увидел, была по запросу со временем ответа около секунды. Кажется странным получать ошибку тайм-аута, когда запрос не может быть превышен по времени на сервере приложений.

Это может быть проблема, похожая на этот вопрос , хотя я не мог точно сказать из представленной информации. Кроме того, у меня нет дополнительного балансировщика нагрузки, просто ELB прямо в Tomcat.

7
ittupelo

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

Есть две непосредственные причины для получения 504 от ELB:

  1. Приложение на самом деле заняло больше времени, чем время ожидания соединения ELB, чтобы ответить. Это медленный тайм-аут - 504, как правило, будет возвращается через несколько секунд, по умолчанию для ELB 60 секунд В этом случае необходимо либо увеличить ELB превышение времени ожидания соединения или повышение производительности приложения.
  2. Приложение вообще не отвечает на ELB, вместо этого закрывает соединение при запросе данных. Это быстрый тайм-аут - 504 обычно возвращается в течение нескольких миллисекунд, что значительно меньше установка времени ожидания ELB.

Первым сценарием было то, что я увидел и решил, увеличив время ожидания ELB. Второй сценарий описывает запутанное поведение, которое я наблюдал после увеличения времени ожидания ELB. Мои файлы журналов имели шаблон «-1 -1 -1», как в примере журналов из статьи:

2015-12-11T13:42:07.736195Z my-elb 10.0.0.1:59893 - -1 -1 -1 504 0 0 0 "GET http://my-elb/ HTTP/1.1" "curl/7.19.7" - -

Из заключения:

Короче говоря, тайм-аут соединения ELB должен быть установлен ниже, чем оба Тайм-ауты приложения и ожидания активности для предотвращения ложных 504-х от того, чтобы быть сгенерированным.

В какой-то момент во время разработки, прежде чем я начал использовать ELB, я установил таймаут Tomcat так, чтобы он оказался выше, чем тайм-аут ELB по умолчанию. Когда я увеличил тайм-аут ELB, я сделал его выше, чем connectionTimeout, который я установил в Tomcat. Увеличение значения connectionTimeout немного выше, чем мой новый тайм-аут ELB, избавило от тайных ошибок 504. Итак, теперь я избавился от «медленных» и «быстрых» ошибок тайм-аута.

Tomcat также имеет параметр keepAliveTimeout, который по умолчанию совпадает с параметром connectionTimeout, если он не установлен. Я не установил его, поэтому изменения connectionTimeout было достаточно, чтобы решить мою проблему.

2
ittupelo

ELB, скорее всего, не является причиной проблемы, но вместо этого показывает, что она у вас есть. Ошибка 504 - это Время ожидания шлюза , которая возникает, когда сервер (в данном случае Tomcat) не отвечает достаточно быстро.

(Я использую ELB для служб с чрезвычайно высокой нагрузкой в ​​течение многих лет и не согласен с ответом на ссылку на другой ответ SO. Хотя это технически верно и может быть верно с чрезвычайно высокая скорость пакетной передачи, например, тысячи запросов в секунду, если ваш объем не будет таким высоким, я бы сначала посмотрел на ваше приложение.)

Самый очевидный тест, подтверждающий, что это не ELB, - это тестирование запросов непосредственно к одному из серверов Tomcat в вашем кластере. Если вы не можете направить к экземплярам Tomcat, вы можете попробовать curl для localhost из экземпляра, который вы хотите протестировать.

Также обратите внимание, что для ELB есть параметр проверки работоспособности, который позволяет вам устанавливать определенные правила, определяющие работоспособность сервера - в противном случае ELB удалит его из кластера, пока он снова не будет исправен. Здоровье может включать своевременный ответ. Посмотрите на CloudWatch для ELB, чтобы увидеть, были ли недавно нездоровые экземпляры.

Если вы видели 504 в разработке, а сейчас это происходит чаще, я бы предположил, что это на самом деле проблема с нагрузкой или производительностью. Наиболее типичным является то, что в Java возникают проблемы с сборкой мусора из-за проблем с базовым приложением. Посмотрите на метрики CloudWatch для ваших экземпляров EC2, чтобы увидеть, высока ли память или процессор или spikey. 

1
Tom Harrison Jr