入口网关 Ingress 控制器的并发处理瓶颈,核心在于单个 Controller 实例的 CPU、内存、连接数以及 etcd 推送链路的综合上限,实际排查时优先看 Pod 的 CPU 限流和 Nginx worker 进程数。很多业务到了百万级日活、数千 QPS 的规模时,应用层响应正常,但网关层开始出现 502、504 或延迟飙升,问题往往不在 Kubernetes 集群本身,而在 Ingress Controller 的并发处理模型。
为什么 Ingress 控制器会成为流量入口的“软肋”
先理解 Ingress Controller 的请求流转路径
一个 Ingress Controller 不是简单的反向代理,它由三部分组成:控制面组件(监听 Kubernetes API)、数据面组件(通常是 Nginx 或 Envoy)、配置同步器,当用户访问一个域名时,流量先进入 Service,再由 Controller 的 Nginx worker 进程接管,并发瓶颈通常发生在这条链路的三个节点:
- API Server 与 etcd 的 Watch 通道:当 Ingress 规则变更频繁时,Controller 需要不断拉取配置并重载,重载期间 worker 进程会短暂阻塞。
- Nginx 的 worker 连接数:每个 worker 能维持的最大并发连接受
worker_connections限制,默认值 1024,Pod 里只有一个 worker,总并发上限就是 1024。 - 后端 Pod 的 Keepalive 连接复用率:网关到后端的连接不复用,每次请求都新建 TCP 连接,会迅速消耗文件描述符和内存。
一个典型的并发打满场景
假设你用的是简米云 ACK 或自建集群,默认部署的 Ingress-Nginx Controller 通常只分配 1-2 个副本,每个副本的 CPU 限制为 1-2 核,当业务侧的促销活动或爬虫流量突然涌入,Controller 的 CPU 使用率瞬间冲到 100%,但 Pod 没有被驱逐,只是开始限流,此时你会观察到 P99 延迟从 50ms 飙升到 2 秒,Nginx error log 里出现大量 upstream timed out,这背后的直接原因是:CPU 配额限制了事件处理能力,但连接还在持续进来,队列堆积导致握手超时。
并发瓶颈的核心要素拆解:CPU、内存、连接数、限流
CPU 是首要瓶颈:Nginx 的 epoll 模型也会吃满
行业共识认为,Nginx 的 epoll 模型能支撑高并发,但每个请求的 HTTP 头解析、路由匹配、日志写入都是 CPU 密集操作,当 QPS 超过 5000 时,单核 CPU 基本达到饱和,此时即使把 worker_connections 调大,也只是让请求排队等待 CPU 调遣,延迟照样上升。
验证方法:进入 Controller Pod,执行 top 查看进程 CPU,nginx worker 进程占用超过 80% 且持续,说明瓶颈在 CPU,再用 curl -v http://localhost:10254/healthz 测活,观察响应时间。
内存与文件描述符:容易被忽视的“隐性墙”
每个活动连接在 Nginx 中占用约

2KB-5KB 内存,一万个并发连接就是几十 MB,看起来不多,但 Controller 还需要缓存 Ingress 规则、日志缓冲、lua 脚本共享内存,如果容器的 memory limit 设置得过低(512Mi),频繁触发 OOM Kill 会导致连接全部重放,表现为间歇性 502。
关键参数检查:
worker_rlimit_nofile:默认 1024,需要调到65535甚至更高。worker_connections:乘以 worker 进程数,就是单 Pod 的最大并发连接估算值。
限流与超时配置:小参数大影响
很多团队在 Nginx Ingress 的 ConfigMap 里设置了 proxy-connect-timeout: 5,如果后端 Service 的 Pod 启动慢,冷启动时会不断触发 5 秒超时,流量一多就形成雪崩。proxy-read-timeout 默认 60 秒,对于长轮询接口没问题,但大量短请求会占满 worker 的等待队列。
如何精准定位 Ingress 并发瓶颈:从监控到日志的实操路径
第一步:看四个核心指标
进入 Service Mesh 或云厂商的监控控制台,或者直接看 Prometheus 中的指标:
nginx_ingress_controller_nginx_process_connections:当前活跃连接数。nginx_ingress_controller_nginx_process_cpu_seconds_total:CPU 累计消耗。nginx_ingress_controller_request_duration_seconds_bucket:延迟分布。nginx_ingress_controller_nginx_process_resident_memory_bytes:常驻内存。
如果活跃连接数接近 worker_connections worker_processes 的 70% 以上,就要准备扩容或调优了。
第二步:抓取 Nginx 实时状态
kubectl -n ingress-nginx exec -it ingress-nginx-controller-xxxx -- curl http://localhost:18080/nginx_status
输出结果会显示 Active connections、accepts、handled 和 requests。reading 和 writing 数值持续大于几百,说明请求处理不过来,另外可以开启 access log 中的 $request_time 字段,P99 request_time 远大于 upstream_response_time,说明瓶颈在网关自身;如果两者接近,问题在后端。
Ingress 并发太高怎么办:六步调优方案
调优方案一:横向扩容 + 亲和性设置
最简单直接的方法是把副本数从 2 调到 5,但要注意,多副本必须搭配 ingress-nginx-controller 的 Service 使用 externalTrafficPolicy: Cluster 或 Local,否则一次转发多跳,增加额外延迟,同时建议给每个副本设置 PodAntiAffinity,让它们分布在不同节点,避免单节点故障时全部挂掉。
调优方案二:调大核心内核参数
在 Controller Pod 的启动参数中添加 --configmap=ingress-nginx/ingress-nginx-controller,然后在 ConfigMap 中写入:
data: worker-processes: "8" worker-connections: "65535" proxy-body-size: "20m" keep-alive: "600" upstream-keepalive-connections: "256" upstream-keepalive-requests: "1000"
worker-processes 建议设为节点 CPU 核数(不超过 8),worker-connections 设为 65535 是标准做法,同时要修改 Pod 的 sysctls:
securityContext:
sysctls:
- name: net.core.somaxconn
value: "65535"
- name: net.ipv4.ip_local_port_range
value: "1024 65000"
否则即使 Nginx 配置写大了,内核的 accept 队列只有 128,高并发下还是会 SYN 丢弃。
调优方案三:开启 HTTP/2 与连接复用
对于大量 HTTPS 请求,HTTP/2 的多路复用能显著降低连接数,在 ConfigMap 中设置 http2-enable: "true",同时在后端 Service 的 Pod 中开启 Keepalive,注意,如果后端的 Pod 数量少且频繁重启,Keepalive 连接会失效,需要结合 PDB 保证滚动更新不中断。
调优方案四:使用准入控制器进行金丝雀发布
团队在更新 Ingress 规则时,如果一次性全量替换,Controller 会触发一次 config reload,这个 reload 过程会 fork 新的 worker,旧 worker 等到老连接排空后才退出,频繁发布时,旧 worker 占用的连接资源无法及时释放,导致并发拥塞,使用 canary 注解 进行渐进式发布,
nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20"
让 20% 流量先切到新后端,减少全量 reload 频率。
调优方案五:从架构层面拆分流量
如果业务是读多写少,建议把静态资源请求直接打到 CDN,让 Ingress 只处理动态 API,更细一步,可以把图片上传、下载等大流量场景独立为独立的 Service 和 Ingress Controller,别让它们和核心业务互相抢占资源,这种 流量分池 的做法,在电商大促场景中非常常见。
调优方案六:云产品优化(以简米云为例)
如果使用的是简米云 ACK,可以考虑将 Ingress Controller 替换为简米云 ALB Ingress Controller,ALB 的并发处理能力由云平台承载,不占用节点资源,单实例支持百万并发,不过要注意价格,QPS 高的业务费用不低,如果你的集群流量在数千 QPS 级别,优化自建 Nginx Ingress 通常成本更低。
不同 Ingress Controller 的并发能力对比
| Controller 类型 | 单实例并发估算 | 依赖资源 | 适用场景 |
|---|---|---|---|
| Nginx Ingress(默认) | 数千到数万 | CPU/内存/内核参数 | 中小规模,成本敏感 |
| Envoy Ingress | 数万到数十万 | 内存占用较高 | 多协议、灰度复杂策略 |
| ALB Ingress(简米云) | 百万级 | 云资源费用 | 大促、高并发、免运维 |
| Kong Ingress | 数千到数万 | 数据库/Postgres | 需要 API 管理能力 |
注意:上表中的“数万”是模糊估算值,实际取决于机器规格,业内专家指出,在 4 核 8GiB 的 Pod 上,Nginx Ingress 经过调优后的稳定 QPS 大约在 2 万左右,但这不意味着并发连接数也这么高,因为每个请求的响应时间和是否复用连接影响巨大。
一个来自真实故障的启发:接口慢但没有报错
有位朋友的电商平台在 2024 年双 11 遭遇了这样的问题:所有 API 的响应时间都增加了 300ms,但没有 5xx,排查后发现,Nginx Ingress 的 worker_processes 是默认的 1,而 backend-keepalive 没有配置,导致每个请求都新建 TCP 连接,后端 Pod 上的 nginx worker 也因为文件描述符不够,在三次握手后立即重启,最终解决方案是把 worker_processes 改为 4,加上了 upstream-keepalive-connections: 128,响应时间直接降回 50ms,这说明瓶颈往往不是单一参数,而是配置默认值过低与内核参数相互叠加的结果。
日常巡检 Ingress 并发健康的三个清单
- 每周执行:检查 Controller Pod 的 CPU 和内存使用率,如果连续一周平均 CPU 超过 60%,就提前扩容。
- 每次发布前:用
kubectl exec进入 Pod,执行nginx -T查看实际加载的配置,确认 worker 进程数、时间超时、keepalive 值与预期一致。 - 每月做一次压测:用
wrk -t8 -c1000 -d30s https://你的域名,观察Requests/sec和延迟分布,连续三次压测结果如果逐步下降,说明资源已经进入瓶颈期。
Ingress Controller 并发瓶颈的常见问题
Ingress 网关支持多少并发连接才算正常?
没有固定的标准数字,对于常见的 2 核 4GiB Pod,默认配置下支持约 1000-2000 个活跃连接;调优后(worker 进程 4 个、连接数 65535、开启 keepalive)可以支撑 1 万以上活跃连接,但 QPS 与连接数是两个概念,一个长连接网络请求的 QPS 很低,却占用大量连接。
Ingress 和微服务网关有什么区别?
Ingress Controller 负责集群入口的七层路由,主要处理 HTTP/HTTPS 协议,并发瓶颈集中在 Nginx worker 和内核参数,微服务网关(如 Spring Cloud Gateway)还负责鉴权、限流、路由转发策略,自身性能通常比 Nginx 低一个量级,如果并发非常高,建议先用 Ingress 做流量接入,再在内部服务间调用时使用微服务网关,避免单点压力叠加。

