Heroku H13错误与乘客

时间:2018-05-03 16:29:59

标签: ruby-on-rails heroku error-handling passenger sigterm

当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之后完成并正常关闭?我的配置中是否有一些我遗漏的东西?

1 个答案:

答案 0 :(得分:2)

在HTTP请求 - 响应生命周期中有三个阶段,SIGTERM可能会到达这个阶段:

  1. 请求仍在流式传输到服务器(在这种情况下,请求未被完全接收且某些数据丢失)。

  2. 正在处理请求。

  3. 响应正在流向客户端。

  4. 作为服务器作者(碘),可以选择保护哪些阶段免受关机相关的断开连接(如果有的话)。

    (第1阶段):

    我非常确定没有服务器可以保护仍在流式传输的请求(这可能会使服务器暴露在关机过程中减慢客户端攻击)。

    (第2阶段):

    在请求处理期间,服务器本身就是客户端正在等待的服务器。在继续关闭过程之前,所有服务器(AFAIK)都会等待响应完成(或超时)。

    (第3阶段):

    通常的做法是限制传出流,防止慢速客户端攻击,同时允许普通客户端完成下载响应。

    碘在这个阶段允许10秒钟,这是硬编码的。我找不到任何configuration option for Passenger所以也许它也是一个硬编码的东西(或者它可能不存在)。

    总结一下:我会考虑使用慢速客户端测试多个服务器并测试其关闭顺序。

    您决定使用哪种服务器,某些客户端可能仍会遇到突然断开连接。

    这可能不是您可以控制或解决的问题,但它可以测试并最小化。

      

    不是Passenger应该允许一些默认时间让进程在SIGTERM之后完成并正常关闭吗?

    这取决于乘客,并不是一项要求。

    此外,在the documentation中无法控制此类设置。这可能是一个重要的缺席(强烈表明乘客不支持此功能)。

      

    我的配置中是否有一些东西可以丢失?

    nginx配置不控制Passenger配置。它们与学位有关,但它们并不相同。

    AFAIK无法控制此关机选项。