首页 > 解决方案 > 当工作线程池变得太大时,带有undertow的Springboot变得无响应

问题描述

我们在 Amazon EC2 上的 k8s 上运行 spring-boot 微服务,使用 undertow 作为我们的嵌入式 Web 服务器。

每当 - 无论出于何种原因 - 我们的下游服务被传入的请求所淹没,并且下游 pod 的工作队列变得太大(我已经看到这个问题发生在 400-ish),然后 spring-boot 完全停止处理排队的请求并且应用程序静音。

通过 JMX 监控队列大小,我们可以看到队列大小继续增长,因为 IO 工作线程排队的请求越来越多 - 但此时任何工作线程都不会处理排队的请求。

我们看不到任何日志输出或任何表明这可能发生的原因。

这个问题在上游级联,因此瘫痪的下游 pod 会导致上游 pod 中的流量遇到相同的问题,并且它们也变得无响应 - 即使我们关闭了通过 API 网关的所有传入流量。

为了解决这个问题,我们必须停止上游的传入流量,然后杀死所有受影响的 Pod,然后再让它们重新启动并重新打开流量。

有人对此有任何想法吗?这是预期的行为吗?如果是这样,我们如何才能在队列大小变得太大并终止服务之前进行拒绝连接?如果不是,是什么导致了这种行为?

非常感谢。亚伦。

标签: spring-bootkubernetesundertow

解决方案


我不完全确定调整 Spring Boot 版本/嵌入式 Web 服务器是否可以解决此问题,但以下是如何使用 Kubernetes/Istio 扩展此问题。

  • 活性探针

如果 livenessProbe 配置正确,则 Kubernetes 会在 Pod 不活动时重新启动它们。https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#define-a-liveness-http-request

  • 水平 Pod 自动扩缩器

根据 CPU 利用率或自定义指标增加/减少 pod 的副本数。https://kubernetes.io/docs/tasks/run-application/horizo​​ntal-pod-autoscale/

  • 垂直 Pod 自动扩缩器

根据负载增加/减少 POD 的 CPU / RAM。https://cloud.google.com/kubernetes-engine/docs/concepts/verticalpodautoscaler

  • 集群自动扩缩器

根据负载增加/减少集群中的节点数。https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler

  • Istio 限速和重试机制

限制服务将接收的请求数量并为无法执行的请求提供重试机制 https://istio.io/docs/tasks/traffic-management/request-timeouts/ https://istio。 io/docs/concepts/traffic-management/#network-resilience-and-testing


推荐阅读