ruby-on-rails - 乘客的 Heroku H13 错误
问题描述
当测功机由于自动缩放而关闭时,我在 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 小时内,我看到大约 16 个 H13 错误,原因是来自测功机缩减事件的 SIGTERM。我可以在我的 Heroku 指标仪表板中证实测功机按比例缩小到 H13。Heroku 支持告诉我,乘客默认允许 30 秒(尽管我不确定他们是否在谈论他们自己的 H12 错误,该错误将在 30 秒后抛出,但我在这里看不到 H12)。
在 SIGTERM 之后,Passenger 不应该允许一些默认时间来完成进程并正常关闭吗?我的配置中是否有我遗漏的东西?
解决方案
在 HTTP 请求-响应生命周期中,SIGTERM 可能会到达三个阶段:
请求仍在流式传输到服务器(在这种情况下,请求尚未完全接收,并且缺少一些数据)。
正在处理请求。
响应正在流式传输到客户端。
作为服务器作者(碘),可以选择保护哪些阶段免受与关闭相关的断开连接(如果有)。
(阶段1):
我很确定没有服务器会保护仍在流式传输的请求(这可能会使服务器在关闭过程中受到缓慢的客户端攻击)。
(第 2 阶段):
在请求处理期间,服务器本身就是客户端正在等待的那个。所有服务器(AFAIK)在继续关闭过程之前等待响应完成(或超时)。
(第 3 阶段):
限制传出流也是一种常见做法,以防止慢速客户端攻击,同时允许普通客户端完成下载响应。
在这个阶段,碘允许 10 秒,这是硬编码的。我找不到Passenger的任何配置选项,所以也许它也是一个硬编码的东西(或者它可能不存在)。
总结一下:我会考虑使用慢速客户端测试一些服务器并测试它们的关闭顺序。
无论您决定使用哪台服务器,某些客户端可能仍会突然断开连接。
这可能不是您可以控制或解决的问题,但您可以对其进行测试和最小化。
在 SIGTERM 之后,Passenger 不应该允许一些默认时间来完成进程并正常关闭吗?
这取决于乘客,不是要求。
此外,文档中没有控制此类设置的选项。这可能是一个重要的缺席(强烈表明乘客不支持此功能)。
我的配置中是否有我遗漏的东西?
nginx 配置不控制乘客配置。它们与学位相关联,但它们并不相同。
AFAIK 无法控制此关闭选项。
推荐阅读
- amazon-web-services - AWS批处理 - 如何限制并发作业的数量
- php - 贝宝 IPN PHP API
- matlab - 八度误差:水平尺寸不匹配 - 矩阵元素matlab
- jquery - 向剑道ui网格添加新行时如何使用模板?
- javascript - 当值为 false 时,绑定 required 和 attr.required 无法按预期工作
- postgresql - 数据服务 wso2 创建生成响应
- pyspark - 集成调试 pyspark 数据帧有时会输出到终端而不是调试控制台
- swift - 有没有办法在另一个范围内使用我的音乐类型数组?
- amazon-web-services - AWS - EBS 快照超出免费套餐
- youtube-iframe-api - YouTube Player API 无法自动启动(使用规范示例)