当dyno由于自动缩放而关闭时,我在Heroku中一直收到H13错误。 H13错误表示在给出响应之前已关闭连接。
从日志中,您可以看到Heroku在缩放dynos时发送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小时内,由于来自dyno缩小事件的SIGTERM,我看到大约16个H13错误。我可以在我的Heroku指标仪表板中证实dyno缩小到H13。 Heroku支持告诉我,乘客默认允许30秒(虽然我不确定他们是否在谈论他们自己的H12错误,这会在30秒后抛出,但我在这里看不到H12。)
是不是Passenger应该允许一些默认时间让进程在SIGTERM之后完成并正常关闭?我的配置中是否有一些我遗漏的东西?
答案 0 :(得分:2)
在HTTP请求 - 响应生命周期中有三个阶段,SIGTERM可能会到达这个阶段:
请求仍在流式传输到服务器(在这种情况下,请求未被完全接收且某些数据丢失)。
正在处理请求。
响应正在流向客户端。
作为服务器作者(碘),可以选择保护哪些阶段免受关机相关的断开连接(如果有的话)。
(第1阶段):
我非常确定没有服务器可以保护仍在流式传输的请求(这可能会使服务器暴露在关机过程中减慢客户端攻击)。
(第2阶段):
在请求处理期间,服务器本身就是客户端正在等待的服务器。在继续关闭过程之前,所有服务器(AFAIK)都会等待响应完成(或超时)。
(第3阶段):
通常的做法是限制传出流,防止慢速客户端攻击,同时允许普通客户端完成下载响应。
碘在这个阶段允许10秒钟,这是硬编码的。我找不到任何configuration option for Passenger所以也许它也是一个硬编码的东西(或者它可能不存在)。
总结一下:我会考虑使用慢速客户端测试多个服务器并测试其关闭顺序。
您决定使用哪种服务器,某些客户端可能仍会遇到突然断开连接。
这可能不是您可以控制或解决的问题,但它可以测试并最小化。
不是Passenger应该允许一些默认时间让进程在SIGTERM之后完成并正常关闭吗?
这取决于乘客,并不是一项要求。
此外,在the documentation中无法控制此类设置。这可能是一个重要的缺席(强烈表明乘客不支持此功能)。
我的配置中是否有一些东西可以丢失?
nginx配置不控制Passenger配置。它们与学位有关,但它们并不相同。
AFAIK无法控制此关机选项。