乐趣区

关于云计算:Nginx-Ingress-高并发实践

概述

Nginx Ingress Controller 基于 Nginx 实现了 Kubernetes Ingress API,Nginx 是公认的高性能网关,但如果不对其进行一些参数调优,就不能充分发挥出高性能的劣势。之前咱们在 Nginx Ingress on TKE 部署最佳实际 一文中讲了 Nginx Ingress 在 TKE 上部署最佳实际,波及的部署 YAML 其实曾经蕴含了一些性能方面的参数优化,只是没有提及,本文将持续开展介绍针对 Nginx Ingress 的一些全局配置与内核参数调优的倡议,可用于撑持咱们的高并发业务。

内核参数调优

咱们先看下如何对 Nginx Ingress 进行内核参数调优,设置内核参数的办法能够用 initContainers 的形式,前面会有示例。

调大连贯队列的大小

过程监听的 socket 的连贯队列最大的大小受限于内核参数 net.core.somaxconn,在高并发环境下,如果队列过小,可能导致队列溢出,使得连贯局部连贯无奈建设。要调大 Nginx Ingress 的连贯队列,只须要调整 somaxconn 内核参数的值即可,但我想跟你分享下这背地的相干原理。

过程调用 listen 零碎调用来监听端口的时候,还会传入一个 backlog 的参数,这个参数决定 socket 的连贯队列大小,其值不得大于 somaxconn 的取值。Go 程序规范库在 listen 时,默认间接读取 somaxconn 作为队列大小,但 Nginx 监听 socket 时没有读取 somaxconn,而是有本人独自的参数配置。在 nginx.conf 中 listen 端口的地位,还有个叫 backlog 参数能够设置,它会决定 nginx listen 的端口的连贯队列大小。

server {
    listen  80  backlog=1024;
    ...

如果不设置,backlog 在 linux 上默认为 511:

backlog=number
   sets the backlog parameter in the listen() call that limits the maximum length for the queue of pending connections. By default, backlog is set to -1 on FreeBSD, DragonFly BSD, and macOS, and to 511 on other platforms.

也就是说,即使你的 somaxconn 配的很高,nginx 所监听端口的连贯队列最大却也只有 511,高并发场景下可能导致连贯队列溢出。

不过这个在 Nginx Ingress 这里状况又不太一样,因为 Nginx Ingress Controller 会主动读取 somaxconn 的值作为 backlog 参数写到生成的 nginx.conf 中:https://github.com/kubernetes…

也就是说,Nginx Ingress 的连贯队列大小只取决于 somaxconn 的大小,这个值在 TKE 默认为 4096,倡议给 Nginx Ingress 设为 65535: sysctl -w net.core.somaxconn=65535

扩充源端口范畴

高并发场景会导致 Nginx Ingress 应用大量源端口与 upstream 建设连贯,源端口范畴从 net.ipv4.ip_local_port_range 这个内核参数中定义的区间随机选取,在高并发环境下,端口范畴小容易导致源端口耗尽,使得局部连贯异样。TKE 环境创立的 Pod 源端口范畴默认是 32768-60999,倡议将其扩充,调整为 1024-65535: sysctl -w net.ipv4.ip_local_port_range="1024 65535"

TIME_WAIT 复用

如果短连贯并发量较高,它所在 netns 中 TIME_WAIT 状态的连贯就比拟多,而 TIME_WAIT 连贯默认要等 2MSL 时长才开释,长时间占用源端口,当这种状态连贯数量累积到超过一定量之后可能会导致无奈新建连贯。

所以倡议给 Nginx Ingress 开启 TIME_WAIT 重用,即容许将 TIME_WAIT 连贯从新用于新的 TCP 连贯:sysctl -w net.ipv4.tcp_tw_reuse=1

调大最大文件句柄数

Nginx 作为反向代理,对于每个申请,它会与 client 和 upstream server 别离建设一个连贯,即占据两个文件句柄,所以实践上来说 Nginx 能同时解决的连贯数最多是零碎最大文件句柄数限度的一半。

零碎最大文件句柄数由 fs.file-max 这个内核参数来管制,TKE 默认值为 838860,倡议调大:sysctl -w fs.file-max=1048576

配置示例

给 Nginx Ingress Controller 的 Pod 增加 initContainers 来设置内核参数:

      initContainers:
      - name: setsysctl
        image: busybox
        securityContext:
          privileged: true
        command:
        - sh
        - -c
        - |
          sysctl -w net.core.somaxconn=65535
          sysctl -w net.ipv4.ip_local_port_range="1024 65535"
          sysctl -w net.ipv4.tcp_tw_reuse=1
          sysctl -w fs.file-max=1048576

全局配置调优

除了内核参数须要调优,Nginx 自身的一些配置也须要进行调优,上面咱们来具体看下。

调高 keepalive 连贯最大申请数

Nginx 针对 client 和 upstream 的 keepalive 连贯,均有 keepalive_requests 这个参数来管制单个 keepalive 连贯的最大申请数,且默认值均为 100。当一个 keepalive 连贯中申请次数超过这个值时,就会断开并从新建设连贯。

如果是内网 Ingress,单个 client 的 QPS 可能较大,比方达到 10000 QPS,Nginx 就可能频繁断开跟 client 建设的 keepalive 连贯,而后就会产生大量 TIME_WAIT 状态连贯。咱们应该尽量避免产生大量 TIME_WAIT 连贯,所以,倡议这种高并发场景应该增大 Nginx 与 client 的 keepalive 连贯的最大申请数量,在 Nginx Ingress 的配置对应 keep-alive-requests,能够设置为 10000,参考:https://kubernetes.github.io/…

同样的,Nginx 与 upstream 的 keepalive 连贯的申请数量的配置是 upstream-keepalive-requests,参考:https://kubernetes.github.io/…

然而,个别状况应该不用配此参数,如果将其调高,可能导致负载不均,因为 Nginx 与 upstream 放弃的 keepalive 连贯过久,导致连贯产生调度的次数就少了,连贯就过于 “ 固化 ”,使得流量的负载不平衡。

调高 keepalive 最大闲暇连接数

Nginx 针对 upstream 有个叫 keepalive 的配置,它不是 keepalive 超时工夫,也不是 keepalive 最大连接数,而是 keepalive 最大闲暇连接数。

它的默认值为 32,在高并发下场景下会产生大量申请和连贯,而事实世界中申请并不是齐全平均的,有些建设的连贯可能会短暂闲暇,而闲暇连接数多了之后敞开闲暇连贯,就可能导致 Nginx 与 upstream 频繁断连和建连,引发 TIME_WAIT 飙升。在高并发场景下能够调到 1000,参考:https://kubernetes.github.io/…

调高单个 worker 最大连接数

max-worker-connections 管制每个 worker 过程能够关上的最大连接数,TKE 环境默认 16384,在高并发环境倡议调高,比方设置到 65536,这样能够让 nginx 领有解决更多连贯的能力,参考:https://kubernetes.github.io/…

配置示例

Nginx 全局配置通过 configmap 配置(Nginx Ingress Controller 会 watch 并主动 reload 配置):

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-controller
# nginx ingress 性能优化: https://www.nginx.com/blog/tuning-nginx/
data:
  # nginx 与 client 放弃的一个长连贯能解决的申请数量,默认 100,高并发场景倡议调高。# 参考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#keep-alive-requests
  keep-alive-requests: "10000"
  # nginx 与 upstream 放弃长连贯的最大闲暇连接数 (不是最大连接数),默认 32,在高并发下场景下调大,防止频繁建联导致 TIME_WAIT 飙升。# 参考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#upstream-keepalive-connections
  upstream-keepalive-connections: "200"
  # 每个 worker 过程能够关上的最大连接数,默认 16384。# 参考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#max-worker-connections
  max-worker-connections: "65536"

总结

本文分享了对 Nginx Ingress 进行性能调优的办法及其原理的解释,包含内核参数与 Nginx 自身的配置调优,更好的适配高并发的业务场景,心愿对大家有所帮忙。

参考资料

  • Nginx Ingress on TKE 部署最佳实际:https://mp.weixin.qq.com/s/NA…
  • Nginx Ingress 配置参考:https://kubernetes.github.io/…
  • Tuning NGINX for Performance:https://www.nginx.com/blog/tu…
  • ngx_http_upstream_module 官网文档:http://nginx.org/en/docs/http…

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

退出移动版