我们有一个提供 API 的 Node.js App Engine 服务。
很少(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 https://groups.google.com/g/google-appengine/c/6gvlur9tXW0/m/bXzY_qAYBAAJ,但该线程在解决之前已关闭。
解决方案
将 server.keepAliveTimeout 设置为 700 秒(或至少 650 秒,加上良好的网络延迟缓冲区)。例如:
const server = http.createServer({ keepAliveTimeout: 700_000 }, app)
server.listen(port, () => console.log('Server listening'));
原因
如果您收到错误“上游过早关闭连接”,则意味着谷歌前端 (GFE) https://cloud.google.com/docs/security/infrastructure/design#google_front_end_service收到请求并转发给nginx,nginx收到请求并转发给应用程序。然后,Ngnix 等待响应,但应用程序没有得到响应,而是关闭了连接,因此它不能再用于接收响应。由于它必须将响应发送回客户端,因此它会向 GFE 发送 502 响应。
这通常是由于应用程序的连接保活超时小于 nginx 上的保活超时,从而导致服务终止连接之间的竞争条件。 Google 在 GAE 上配置的 nginx keepalive_timeout 为 650 秒,以避免与超时为 600 秒的 Google 云负载均衡器 (GCLB) 发生竞争状况。
竞争条件的发生就好像超时在基础设施的深处变得更短一样,外部包装器可能会在内部服务关闭连接时尝试重用连接。例如,如果您的应用程序的超时时间为 5 秒(Node.js 中的默认设置 https://nodejs.org/docs/latest-v18.x/api/http.html#serverkeepalivetimeout):
- t0:nginx收到请求,打开连接并转发
- t5:nginx 收到另一个请求,重用该连接(当 5
这是更详细的解释(仅涉及 GCLB -> 您的应用程序,而不是 GCLB -> nginx -> 您的应用程序):https://blog.percy.io/tuning-nginx-behind-google-cloud-platform-http-s-load-balancer-305982ddb340 https://blog.percy.io/tuning-nginx-behind-google-cloud-platform-http-s-load-balancer-305982ddb340
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)