概述

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 高并发实践的更多相关文章

  1. Nginx Ingress 高并发实践

    概述 Nginx Ingress Controller 基于 Nginx 实现了 Kubernetes Ingress API,Nginx 是公认的高性能网关,但如果不对其进行一些参数调优,就不能充分 ...

  2. 心知天气数据API 产品的高并发实践

    心知天气数据API 产品的高并发实践 心知天气作为国内领先的商业气象服务提供商,天气数据API 产品从公司创立以来就一直扮演着很重要的角色.2009 年API 产品初次上线,历经十年,我们不断用心迭代 ...

  3. Nginx突破高并发的性能优化 - 运维笔记

    在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题.今天这里简单梳理下nginx性能优化的配置(仅仅依据本人的实战经验而述,如有不妥,敬请指出~) 一.这里 ...

  4. Linux服务器高并发实践经历

    作为一个师父离职早的野生程序员,业务方面还可以达到忽悠别人的水平,但上升到性能层面那就是硬伤. 真实天上掉馅饼,公司分配了一个测试性能的任务,真是感觉我的天空星星都亮了. 高并发主要限制因素:CPU. ...

  5. Nginx多进程高并发、低时延、高可靠机制在缓存(redis、memcache)twemproxy代理中的应用

    1. 开发背景 现有开源缓存代理中间件有twemproxy.codis等,其中twemproxy为单进程单线程模型,只支持memcache单机版和redis单机版,都不支持集群版功能. 由于twemp ...

  6. Nginx多进程高并发、低时延、高可靠机制在缓存代理中的应用

    1. 开发背景 现有开源缓存代理中间件有twemproxy.codis等,其中twemproxy为单进程单线程模型,只支持memcache单机版和redis单机版,都不支持集群版功能. 由于twemp ...

  7. Nginx多进程高并发、低时延、高可靠机制缓存代理中的应用

    1. 开发背景 现有开源缓存代理中间件有twemproxy.codis等,其中twemproxy为单进程单线程模型,只支持memcache单机版和redis单机版,都不支持集群版功能. 由于twemp ...

  8. nginx处理高并发请求强于apache

    ginx 不同于 Apache2 的一点就是,Nginx 采用单线程,非阻塞,异步 IO 的工作模型. Apache2 对于每一个请求,都会创建一个新进程或线程,会浪费很多内存和 CPU 时间,而 N ...

  9. nginx php-fpm 高并发优化

    PHP-php-fpm配置优化 前言: 1.少安装PHP模块, 费内存 2.调高linux内核打开文件数量,可以使用这些命令(必须是root帐号)(我是修改/etc/rc.local,加入ulimit ...

  10. nginx 实现高并发和高负载

    一.Nginx是如何实现高并发的 service nginx start之后,然后输入#ps -ef|grep nginx,会发现Nginx有一个master进程和若干个worker进程,这些work ...

随机推荐

  1. 实践案例丨云连接CC实现跨区域多VPC与线下IDC Server互联

    摘要:用实践案例带你掌握云连接CC如何实现跨区域多VPC与线下IDC Server互联. [背景] 当前在华为云华南.华东.香港region均部署了业务,同时在华南region通过云专线与线下IDC打 ...

  2. AI开发实践丨客流分析之未佩戴口罩识别

    摘要:通过本教程,我们可以学习客流统计应用的扩展--过线客流统计+口罩佩戴识别,可用于商超.写字楼入口安检. 本文分享自华为云社区<客流分析之未佩戴口罩识别>,作者: HiLens_fei ...

  3. 开发的必杀技:Git 的分支管理

    摘要:作为一名码农,Git的使用就像家常便饭,时时刻刻都要用到,那么Git分支管理也是必须要掌握的. Git 分支管理 几乎每一种版本控制系统都以某种形式支持分支.使用分支意味着你可以从开发主线上分离 ...

  4. 小熊派:用OpenHarmory3.0点亮LED

    摘要:作为一个代表性的完整的开发,本案例可以分成3大部分:代码文件的规划,LED灯的驱动开发,点亮LED的业务开发. 本文分享自华为云社区<在小熊派Micro上用OpenHarmory3.0点亮 ...

  5. Cmder - 想让你的windows下 cmd 和 SecureCRT 操作 Linux 一样帅吗 附字符集编码 chcp 936、chcp 65001

    想让你的windows下 cmd 和 SecureCRT 操作 Linux 一样帅的命令行显示吗. 下载 cmder 绿色版,然后用我的配置文件,替换原来的文件启动就可以了 配置文件下载:cmder ...

  6. AI 0基础学习,数学名词解析

    AI学习过程中,常见的名词解析 中位数 将数据从小到大排序,奇数列,取中间值,偶数列,中间两个值的平均,可做为销售指标 众数 一组数据中,数值出现最多的那个.反映哪款产品,销量最好 平均数 比赛中,去 ...

  7. Jenkins + SVN

    安装插件 Localization: Chinese (Simplified) Subversion 配置国内源 http://mirror.tuna.tsinghua.edu.cn/jenkins/ ...

  8. Hugging Face 音频 AI 派对直播回放(上)

    直播回放视频地址:https://www.bilibili.com/video/BV1nh4y1X7zs/?vd_source=c5a5204620e35330e6145843f4df6ea4 为了庆 ...

  9. 柔性上肢康复机器人研究中的VR技术

    上肢康复机器人用于对脑卒中患者进行上肢康复治疗,能够维持和扩大患者关节活动度.增强肌肉力和协调性,以防止肌肉萎缩.关节痉挛等各类症状的出现,最终重建肢体功能,以便回归正常生活.现有的上肢康复机器人训练 ...

  10. 【Django-Vue】手机号是否存在接口 多方式登录接口 腾讯云短信介绍和申请 api与sdk

    目录 昨日回顾 今日内容 0 登录注册功能设计 1 短信登录接口 视图类 2 多方式密码登录接口 视图类 序列化类 路由 3 腾讯云短信介绍和申请 3.1api与sdk 补充 练习 昨日回顾 # 你的 ...