nginx Google App Engine 502具有“上游过早关闭连接”,似乎无法到达我们的示例

irtuqstp  于 2023-04-20  发布在  Nginx
关注(0)|答案(1)|浏览(210)

我们有一个Node.js App Engine服务,它提供一个API。
很少(500个请求中有1个)向客户端返回502,并从Google Cloud Logging中获取nginx日志中的错误:upstream prematurely closed connection while reading response header from upstream .
这些请求似乎没有到达我们的示例,因为在尝试调试时,我们设置了日志记录,以便在收到任何请求时立即记录。
失败的请求通常看起来很随机。
此问题与https://groups.google.com/g/google-appengine/c/6gvlur9tXW0/m/bXzY_qAYBAAJ中描述的问题非常相似,但此线程在解决之前已关闭。

gab6jxml

gab6jxml1#

解决方案

将您的server.keepAliveTimeout设置为700秒(或至少650秒,加上一个良好的网络延迟缓冲区)。例如:

const server = http.createServer({ keepAliveTimeout: 700_000 }, app)
server.listen(port, () => console.log('Server listening'));

起因

如果你得到错误'上游过早关闭连接',这意味着谷歌前端(GFE)接收到请求并转发给nginx,nginx接收到请求并转发给应用程序。Ngnix然后等待响应,但不是得到响应,而是得到响应。连接被应用程序关闭,因此它不能再用于接收响应。由于它必须将响应发送回客户端,它响应于GFE发送502。
这通常是由于应用程序的连接keepalive超时小于nginx上的keepalive超时,这会导致服务终止连接之间的竞争条件。Google在GAE上配置的nginx keepalive_timeout是650秒,以避免Google Cloud Load Balancers(GCLB)的竞争条件,其超时为600秒。
如果超时在您的基础设施中越深入越短,则可能会发生竞争条件,外部 Package 器可能会在内部服务关闭连接时尝试重用连接。例如,如果您的应用具有5秒的超时(Node.js中的默认设置):

  • t0:nginx接收到一个请求,打开一个连接并转发
  • t5:nginx收到另一个请求,重用连接(因为5〈650,它的超时),并沿着连接转发它。同时您的应用达到其连接超时并告诉nginx它正在关闭连接。

这是更详细的解释(关于GCLB -〉your app,而不是GCLB -〉nginx -〉your app):https://blog.percy.io/tuning-nginx-behind-google-cloud-platform-http-s-load-balancer-305982ddb340

相关问题