繁体   English   中英

AppEngine nodejs 应用偶尔发送 502 并重启

[英]AppEngine nodejs app sporadically sends 502s and restarts

我们有一个成功部署到标准环境的 nodejs 应用程序。 大约两个小时后(或更快,取决于流量)发生了一些事情:我们的下游客户端开始收到一堆 502 响应,然后服务稳定下来。 我们认为这种情况至少已经发生了几个月。

在调查 502 的原因时,我看到:

  • 没有未处理的异常/承诺拒绝日志表明节点应用程序已崩溃
  • 我在收到SIGTERM时 console.log 也没有出现在日志中
  • nginx sidecar的日志包括:
2020/06/16 23:11:11 [error] 35#35: *1149 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 169.254.1.1, server: _, request: "POST /api/redacted HTTP/1.1", upstream: "http://127.0.0.1:8081/api/redacted", host: "redacted.appspot.com""  

我假设 502 来自 nginx,因为上游已经消失。 我应该探索其他解释吗?

如果 GAE 有意替换我的应用程序容器,该过程不应该阻止这些类型的 502 吗?

当应用程序/容器被替换时,我是否应该期望环境发送SIGTERM以外的其他内容?

更新 #1 (2020-06-22)

我调查并发现证据表明我们可能超过了 memory 配额,因此我将 instance_class 从 F1 更改为 F2。 在我写这篇文章时,我们的实例在 memory 的使用量约为 200M(F2 有 512M 可用)。 此外,我使用--max-old-space-size开关将节点 memory 使用设置为 496M。

502 仍在发生。

我怀疑 502 是由于自动缩放器终止实例而发生的。 我们的应用永远不会收到SIGTERM (即使在部署期间)。 这意味着我无法优雅地关闭 http keepalive 连接,这可以解释为什么 nginx 会引发对等方的连接重置。

更新 #2 (2020-06-24)

我们的服务只是标准的 REST 类型的东西,没有沉重的循环。

我将发布另一个更新,其中包含一些 memory 图表,但我没有看到任何尖峰。 也许是一个小的 memory 泄漏。

这是我们的 app.yaml:

service: redacted
runtime: nodejs12
instance_class: F2
handlers:
  - url: /.*
    secure: always
    redirect_http_response_code: 301
    script: auto

通常,502 消息是 nginx 端的错误,正如您所提到的。 与此错误相关的详细日志尚未显示在 Cloud Logging 中。

根据您的行为,这似乎是一种工作量,因此我们可以将此案例与资源耗尽的问题联系起来。

有一些值得一看的东西:

  • 检查您的指标。 memory 和 CPU 使用率应该在健康的限制之下。
  • 检查您的扩展指标是否足以满足您的工作负载。

是否有机会在重启事件附近分享这些指标? 此外,如果您在 app.yaml 中共享您的资源和扩展,那将是很好的。

我们在 App Engine Flexible 上部署的 Node.js 应用程序遇到了非常相似的问题。

在我们的案例中,我们最终确定我们有 memory 压力导致 Node.js 垃圾收集器有时会将请求的处理延迟数百毫秒(有时更多)。 这导致我们的健康检查 URL 偶尔超时,促使 GAE 从活动池中删除该实例。

因为我们通常只有两个实例来处理稳定的流量,删除一个实例很快就会使剩余的实例过载,它很快就会遭受同样的命运。

我们惊讶地发现,App Engine 可能需要两分钟或更长时间才能将流量分配给新创建的实例。 在我们的原始实例被宣布不健康到新实例在线之间,502 将返回(可能是由 GAE 的 nginx)给客户端。

我们只需添加以下内容即可稳定环境:

automatic_scaling:
   min_num_instances: 4

到我们的app.yaml 因为两个实例通常足以处理流量,确保我们始终运行四个显然使我们的 memory 使用率足够低,以防止 GC 停止请求处理,即使它这样做了,我们也有足够的多余容量来处理一个被删除的实例。

GAE 标准的缩放设置略有不同。

回想起来,我们可以看到我们的延迟/响应时间在真正的问题开始之前会变得有点“紧张”。 大多数响应的典型响应时间约为 30 毫秒,但我们会越来越多地看到 x00 毫秒范围内的异常请求。 您可能需要检查您的请求日志以查看是否看到类似的内容。

New Relic 的Node.js VM 数据有助于检测垃圾收集的时间越来越长。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM