Ошибка Heroku H13 с пассажиром

Я постоянно получаю ошибки H13 в Heroku, когда дино отключается из-за автомасштабирования. Ошибка H13 означает, что соединение было закрыто до получения ответа.

Из журналов вы можете видеть, что Heroku отправляет SIGTERM, когда он масштабирует динамометрические станции, и пассажир немедленно отключает любые запросы, которые еще не завершили обработку:

May 03 08:38:24 myapp app/web.4:  App 175 stdout: Started POST "/exams/3167060/tick?elapsed_time=1" for 108.162.237.61 at 2018-05-03 12:38:23 +0000 
May 03 08:38:24 myapp app/web.4:  App 175 stdout: Processing by ExamsController#tick as HTML 
May 03 08:38:24 myapp app/web.4:  App 175 stdout:   Parameters: {"elapsed_time"=>"1", "id"=>"3167060"} 
May 03 08:38:24 myapp app/web.4:  Stopping web server... done 
May 03 08:38:24 myapp heroku/router:  at=info method=POST path="/exams/3167120/tick?elapsed_time=1" host=www.myapp.com request_id=d81b4dc5-2a5a-44a4-96c6-61b7ea6d28f3 fwd="206.221.128.1,162.158.63.225" dyno=web.4 connect=1ms service=37ms status=200 bytes=954 protocol=https 
May 03 08:38:24 myapp heroku/web.4:  Stopping all processes with SIGTERM 
May 03 08:38:24 myapp heroku/router:  at=error code=H13 desc="Connection closed without response" method=POST path="/exams/3167060/tick?elapsed_time=1" host=www.myapp.com request_id=28c2f413-847c-4d11-bce9-5be7186cfbd8 fwd="152.27.48.186,108.162.237.61" dyno=web.4 connect=1ms service=53ms status=503 bytes=0 protocol=https 
May 03 08:38:24 myapp heroku/web.4:  Process exited with status 2

Конфигурация моего Procfile пассажира выглядит следующим образом, и я не установил ничего, связанного с таймаутом:

web: bundle exec passenger start -p $PORT --max-pool-size $MAX_POOL_SIZE --min-instances $MIN_INSTANCES --nginx-config-template config/nginx.conf.erb

В течение 24 часов я вижу около 16 ошибок H13 из-за SIGTERM от события уменьшения масштаба на динамометрическом стенде. Я могу подтвердить масштабирование дино до H13 на моей панели показателей Heroku. Служба поддержки Heroku сообщает мне, что пассажир разрешает 30 секунд по умолчанию (хотя я не уверен, говорят ли они о своей собственной ошибке H12, которая будет выдана через 30 секунд, но я не вижу здесь H12).

Разве Passenger не должен давать время по умолчанию для завершения процессов после SIGTERM и корректного завершения работы? Может быть, что-то в моей конфигурации мне не хватает?


person Manu Kanthan    schedule 03.05.2018    source источник


Ответы (1)


В жизненном цикле HTTP-запроса-ответа есть три этапа, на которых может поступить SIGTERM:

  1. Запрос все еще передается на сервер (в этом случае запрос не был полностью получен и некоторые данные отсутствуют).

  2. Запрос обрабатывается.

  3. Ответ передается клиенту.

Как автор сервера (йод), нужно выбрать, какие этапы будут защищены от отключений, связанных с отключением (если таковые имеются).

(этап 1):

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

(2 этап):

Во время обработки запроса клиент ждет сам сервер. Все серверы (AFAIK) ждут завершения ответа (или тайм-аута), прежде чем продолжить процедуру выключения.

(этап 3):

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

Йод позволяет в течение 10 секунд на этом этапе, который жестко запрограммирован. Мне не удалось найти ни одного варианта конфигурации для Пассажира, так что, возможно, это тоже жестко закодированная вещь (или, может быть, ее не существует).


Подводя итог: я бы рассмотрел возможность тестирования ряда серверов с использованием медленного клиента и проверки их последовательности завершения работы.

Какой бы сервер вы ни выбрали, некоторые клиенты все равно могут испытывать резкие отключения.

Это может быть то, что вы не можете контролировать или решать, но это то, что вы можете проверить и минимизировать.

Разве Passenger не должен давать время по умолчанию для завершения процессов после SIGTERM и корректного завершения работы?

Это зависит от пассажира и не является обязательным требованием.

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

Может быть, что-то в моей конфигурации мне не хватает?

Конфигурация nginx не контролирует конфигурацию Passenger. Они связаны в какой-то степени, но это не одно и то же.

AFAIK нет возможности контролировать эту опцию выключения.

person Myst    schedule 10.05.2018
comment
Спасибо. Я думаю, вы в основном имеете в виду, что я должен переключить серверы приложений, верно? Скорее всего, я собираюсь поэкспериментировать с Puma, так как это рекомендация Heroku. - person Manu Kanthan; 14.05.2018
comment
@ManuKanthan, да. Мне нравится Passenger, и у них отличная команда, но если у вас нет корпоративной версии и нет поддержки этой функции, IMHO Puma - лучший способ пойти (или йод, к которому я склонен ... и не только потому, что он работает лучше в моих тестах, особенно при обслуживании статических файлов, но поскольку я его закодировал, я знаю это лучше). - person Myst; 14.05.2018