GCP 负载均衡器后面的服务器偶尔会收到 502 服务器错误,“failed_to_connect_to_backend”
Server behind GCP Load Balancer occalionally gets 502 Server Error, “failed_to_connect_to_backend”
我们的 GCP 负载均衡器偶尔会 returns 502 对于某些带有“failed_to_connect_to_backend”的请求。它定期发生。在谷歌搜索和搜索 Stack Overflow 时,我发现了这个 link: https://cloud.google.com/load-balancing/docs/https#timeouts_and_retries。我还浏览了几篇关于 GCP 负载均衡器保持活动超时的文章。
我的服务器在 Kubernetes 中 运行 使用率低 CPU 因此后端太忙似乎不是问题。
这是我用来设置 Http 服务器的示例代码:
server := &http.Server{
Addr: addr,
Handler: handler,
ReadHeaderTimeout: 20 * time.Second,
ReadTimeout: 1 * time.Minute,
WriteTimeout: 2 * time.Minute,
IdleTimeout: time.Duration(tcpKeepAliveTimeout) * time.Second,
}
if e := listenAndServe(server, 620); e != nil && e != http.ErrServerClosed {
return err
}
func listenAndServe(srv *http.Server, tcpKeepAliveTimeout int) error {
addr := srv.Addr
if addr == "" {
addr = ":http"
}
lc := net.ListenConfig{
KeepAlive: 620 * time.Second,
}
ln, err := lc.Listen(context.Background(), "tcp", addr)
if err != nil {
return err
}
defer ln.Close()
if err != nil {
return err
}
return srv.Serve(ln)
}
我正在为 TCP Keep-Alive 设置 620 秒超时(在 Google 文档中推荐),但它没有帮助,我仍然收到 502s。我做错了什么?
当 GFE 无法与后端实例建立连接时生成 502 HTTP 响应代码。
502 的常见原因如下,我建议您自行验证:
- 防火墙(实例本身的 GCP 防火墙规则或防火墙软件 运行)阻止流量
- Web 服务器软件未 运行 在后端实例上
- Web 服务器软件在后端实例上配置错误
服务器资源耗尽且不接受连接:
- CPU 使用率太高无法响应
- 内存使用率过高,进程已终止或无法 malloc()
- 已建立的最大 TCP 连接数
- 产生了最大数量的工人并且所有人都很忙(想想 Apache 中的 mpm_prefork)
- 写得不好的服务器实现在负载或non-standard行为下挣扎
这是我发现的:
- 我是 运行 GKE 上的可抢占节点
- 我有一个脚本可以删除 GKE 节点上的所有容器被抢占。
- 我正在通过 nodePort 公开我的服务
- 当节点被抢占时,后端仍然将流量路由到“nodePort”事件节点,直到后端健康检查失败。
- 解决方案是使用容器原生负载平衡从 nodePort 移动到 neg 端点。
我们的 GCP 负载均衡器偶尔会 returns 502 对于某些带有“failed_to_connect_to_backend”的请求。它定期发生。在谷歌搜索和搜索 Stack Overflow 时,我发现了这个 link: https://cloud.google.com/load-balancing/docs/https#timeouts_and_retries。我还浏览了几篇关于 GCP 负载均衡器保持活动超时的文章。
我的服务器在 Kubernetes 中 运行 使用率低 CPU 因此后端太忙似乎不是问题。
这是我用来设置 Http 服务器的示例代码:
server := &http.Server{
Addr: addr,
Handler: handler,
ReadHeaderTimeout: 20 * time.Second,
ReadTimeout: 1 * time.Minute,
WriteTimeout: 2 * time.Minute,
IdleTimeout: time.Duration(tcpKeepAliveTimeout) * time.Second,
}
if e := listenAndServe(server, 620); e != nil && e != http.ErrServerClosed {
return err
}
func listenAndServe(srv *http.Server, tcpKeepAliveTimeout int) error {
addr := srv.Addr
if addr == "" {
addr = ":http"
}
lc := net.ListenConfig{
KeepAlive: 620 * time.Second,
}
ln, err := lc.Listen(context.Background(), "tcp", addr)
if err != nil {
return err
}
defer ln.Close()
if err != nil {
return err
}
return srv.Serve(ln)
}
我正在为 TCP Keep-Alive 设置 620 秒超时(在 Google 文档中推荐),但它没有帮助,我仍然收到 502s。我做错了什么?
当 GFE 无法与后端实例建立连接时生成 502 HTTP 响应代码。
502 的常见原因如下,我建议您自行验证:
- 防火墙(实例本身的 GCP 防火墙规则或防火墙软件 运行)阻止流量
- Web 服务器软件未 运行 在后端实例上
- Web 服务器软件在后端实例上配置错误 服务器资源耗尽且不接受连接:
- CPU 使用率太高无法响应
- 内存使用率过高,进程已终止或无法 malloc()
- 已建立的最大 TCP 连接数
- 产生了最大数量的工人并且所有人都很忙(想想 Apache 中的 mpm_prefork)
- 写得不好的服务器实现在负载或non-standard行为下挣扎
这是我发现的:
- 我是 运行 GKE 上的可抢占节点
- 我有一个脚本可以删除 GKE 节点上的所有容器被抢占。
- 我正在通过 nodePort 公开我的服务
- 当节点被抢占时,后端仍然将流量路由到“nodePort”事件节点,直到后端健康检查失败。
- 解决方案是使用容器原生负载平衡从 nodePort 移动到 neg 端点。