乘客的 Heroku H13 错误
Heroku H13 error with Passenger
当 dyno 由于自动缩放而关闭时,我在 Heroku 中不断收到 H13 错误。 H13 错误意味着在给出响应之前连接已经关闭。
从日志中,您可以看到 Heroku 在缩减 dynos 时发送了一个 SIGTERM,passenger 立即关闭了所有尚未完成处理的请求:
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 错误是由于 dyno 缩小事件的 SIGTERM 造成的。我可以在我的 Heroku 指标仪表板中证实 dyno 缩小到 H13。 Heroku 支持告诉我乘客默认允许 30 秒(虽然我不确定他们是否在谈论他们自己的 H12 错误,该错误会在 30 秒后抛出,但我在这里没有看到 H12)。
Passenger 难道不应该允许一些默认时间让进程在 SIGTERM 之后完成并正常关闭吗?我的配置中是否缺少某些内容?
SIGTERM 可能到达的 HTTP 请求-响应生命周期分为三个阶段:
请求仍在流式传输到服务器(在这种情况下,请求未被完全接收并且一些数据丢失)。
正在处理请求。
响应正在流式传输到客户端。
作为服务器作者 (iodine),可以选择哪些阶段受到保护以防止与关机相关的断开连接(如果有的话)。
(第 1 阶段):
我很确定没有服务器会保护仍在流式传输的请求(这可能会使服务器在关闭过程中受到缓慢的客户端攻击)。
(第 2 阶段):
在请求处理期间,服务器本身就是客户端正在等待的服务器。所有服务器 (AFAIK) 在继续关闭程序之前等待响应完成(或超时)。
(第 3 阶段):
限制传出流也是一种常见的做法,可以防止缓慢的客户端攻击,同时允许普通客户端完成其响应的下载。
Iodine 在此阶段允许 10 秒,这是硬编码的。我找不到任何 configuration option for Passenger 所以也许它也是一个硬编码的东西(或者它可能不存在)。
总而言之:我会考虑使用慢速客户端测试一些服务器并测试它们的关闭顺序。
无论您选择哪个服务器,某些客户端可能仍会遇到突然断开连接的情况。
这可能不是您可以控制或解决的问题,但您可以测试并尽量减少。
Isn't Passenger supposed to allow some default time for the processes to finish after a SIGTERM and gracefully shut down?
这取决于乘客,不是必需的。
此外,the documentation 中没有控制此类设置的选项。这可能是一个严重的缺失(强烈表明乘客不支持此功能)。
Is there perhaps something in my config that I am missing?
nginx 配置不控制 Passenger 配置。它们与学位相关联,但并不相同。
据我所知,无法控制此关闭选项。
当 dyno 由于自动缩放而关闭时,我在 Heroku 中不断收到 H13 错误。 H13 错误意味着在给出响应之前连接已经关闭。
从日志中,您可以看到 Heroku 在缩减 dynos 时发送了一个 SIGTERM,passenger 立即关闭了所有尚未完成处理的请求:
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 错误是由于 dyno 缩小事件的 SIGTERM 造成的。我可以在我的 Heroku 指标仪表板中证实 dyno 缩小到 H13。 Heroku 支持告诉我乘客默认允许 30 秒(虽然我不确定他们是否在谈论他们自己的 H12 错误,该错误会在 30 秒后抛出,但我在这里没有看到 H12)。
Passenger 难道不应该允许一些默认时间让进程在 SIGTERM 之后完成并正常关闭吗?我的配置中是否缺少某些内容?
SIGTERM 可能到达的 HTTP 请求-响应生命周期分为三个阶段:
请求仍在流式传输到服务器(在这种情况下,请求未被完全接收并且一些数据丢失)。
正在处理请求。
响应正在流式传输到客户端。
作为服务器作者 (iodine),可以选择哪些阶段受到保护以防止与关机相关的断开连接(如果有的话)。
(第 1 阶段):
我很确定没有服务器会保护仍在流式传输的请求(这可能会使服务器在关闭过程中受到缓慢的客户端攻击)。
(第 2 阶段):
在请求处理期间,服务器本身就是客户端正在等待的服务器。所有服务器 (AFAIK) 在继续关闭程序之前等待响应完成(或超时)。
(第 3 阶段):
限制传出流也是一种常见的做法,可以防止缓慢的客户端攻击,同时允许普通客户端完成其响应的下载。
Iodine 在此阶段允许 10 秒,这是硬编码的。我找不到任何 configuration option for Passenger 所以也许它也是一个硬编码的东西(或者它可能不存在)。
总而言之:我会考虑使用慢速客户端测试一些服务器并测试它们的关闭顺序。
无论您选择哪个服务器,某些客户端可能仍会遇到突然断开连接的情况。
这可能不是您可以控制或解决的问题,但您可以测试并尽量减少。
Isn't Passenger supposed to allow some default time for the processes to finish after a SIGTERM and gracefully shut down?
这取决于乘客,不是必需的。
此外,the documentation 中没有控制此类设置的选项。这可能是一个严重的缺失(强烈表明乘客不支持此功能)。
Is there perhaps something in my config that I am missing?
nginx 配置不控制 Passenger 配置。它们与学位相关联,但并不相同。
据我所知,无法控制此关闭选项。