精华推荐 | 深入浅出学习透析Nginx服务器的基本原理和配置指南「Keepalive性能分析实战篇」

简介: 精华推荐 | 深入浅出学习透析Nginx服务器的基本原理和配置指南「Keepalive性能分析实战篇」

背景介绍


image.png

  • Linux系统:Centos 7 x64
  • Nginx版本:1.11.5


Nginx 是一款面向性能设计的 HTTP 服务器,能反向代理 HTTP,HTTPS 和邮件相关(SMTP,POP3,IMAP)的协议链接。并且提供了负载均衡以及 HTTP 缓存。它的设计充分使用异步事件模型,削减上下文调度的开销,提高服务器并发能力。采用了模块化设计,提供了丰富模块的第三方模块。所以关于 Nginx,有这些标签:「异步」「事件」「模块化」「高性能」「高并发」「反向代理」「负载均衡」「长连接」。本章内容主要就是针对于长连接请求模块。




为什么要单独讲解keepalive指令?


upstream设置中,有个参数要特别的小心,就是这个keepalive。


大多数未仔细研读过nginx的同学通常都会误解这个参数,有些人理解为这里的keepalive是设置是否打开长连接,以为应该设置为on/off。有些人会被前面的keepalive_timeout误导,以为这里也是设置keepalive的timeout。


但是实际上这个keepalive参数的含义非常的奇特,请小心看nginx文档中的说明,因为Keepalive长连接非常重要而且容易理解错误,所以专门做连一期专门讲解keepalive的文章。


本文介绍如何使用Nginx进行配置和实现长连接Keepalive,并介绍如何设置 nginx 以提供静态内容服务,如何配置 nginx 作为代理服务器。



keepalive指令


支持keepalive长连接,当使用nginx作为反向代理时,为了支持长连接,需要做到两点:


  • 从client到nginx的连接是长连接
  • 从nginx到server的连接是长连接


从HTTP协议的角度看,Nginx在这个过程中,对于客户端它扮演着HTTP服务器端的角色。而对于真正的服务器端(在nginx的术语中称为upstream)Nginx又扮演着HTTP客户端的角色,keepalive指令出现在版本1.1.4。



keepalive指令格式


  • keepalive不是on/off之类的开关
  • keepalive不是timeout,不是用来设置超时值
Syntax:    keepalive connections;
Default:    —
Context:    upstream
Activates the cache for connections to upstream servers.
复制代码

connections的取值代表着连接到upstream服务器的持续连接(即长连接)的数量。很多人都会有一个误解:认为这个参数是设置到upstream服务器的长连接的数量,分歧在于是最大连接数还是最小连接数



官方文档的介绍


The connections parameter sets the maximum number of idle keepalive connections to upstream servers


  • connections参数设置到upstream服务器的空闲keepalive连接的最大数量,这个”idle”的概念,何为idle。大多数人之所以误解为是到upstream服务器的最大长连接数,一般都是因为看到了文档中的这句话,而漏看了这个”idle”一词。


When this number is exceeded, the least recently used connections are closed.


  • 当这个数量被突破时,最近使用最少的连接将被关闭。


Nginx的官方文档给出了指示,否定了最大连接数的可能:keepalive指令不会限制一个nginx worker进程到upstream服务器连接的总数量请注意空闲keepalive连接的最大数量中空闲这个关键字

keepalive实际场景分析


  • 先假设一个场景: 有一个HTTP服务,作为upstream服务器接收请求,响应时间为100毫秒。如果要达到10000 QPS的性能,就需要在nginx和upstream服务器之间建立大约1000条HTTP连接。nginx为此建立连接池,然后请求过来时为每个请求分配一个连接,请求结束时回收连接放入连接池中,连接的状态也就更改为idle。


  • 之后假设这个upstream服务器的keepalive参数设置比较小,比如常见的10.


  • 再次假设请求和响应是均匀而平稳的,那么这1000条连接应该都是一放回连接池就立即被后续请求申请使用,线程池中的idle线程会非常的少,趋进于零。我们以10毫秒为一个单位,来看连接的情况(注意场景是1000个线程+100毫秒响应时间,每秒有10000个请求完成):


  • 每10毫秒有100个新请求,需要100个连接
  • 每10毫秒有100个请求结束,可以释放100个连接
  • 如果请求和应答都均匀,则10毫秒内释放的连接刚好够用,不需要新建连接,连接池空闲连接为零


  • 如果请求通常不是足够的均匀和平稳,为了简化问题,我们假设应答始终都是平稳的,只是请求不平稳,第一个10毫秒只有50,第二个10毫秒有150:


  • 下一个10毫秒,有100个连接结束请求回收连接到连接池,但是假设此时请求不均匀10毫秒内没有预计的100个请求进来,而是只有50个请求。注意此时连接池回收了100个连接又分配出去50个连接,因此连接池内有50个空闲连接。
  • 最后注意看keepalive=10的设置,这意味着连接池中最多容许保留有10个空闲连接。因此nginx不得不将这50个空闲连接中的40个关闭,只留下10个


  • 再下一个10个毫秒,有150个请求进来,有100个请求结束任务释放连接。150 - 100 = 50,空缺了50个连接,减掉前面连接池保留的10个空闲连接,nginx不得不新建40个新连接来满足要求


  • 可以看到,在短短的20毫秒内,仅仅因为请求不够均匀,就导致nginx在前10毫秒判断空闲连接过多关闭了40个连接,而后10毫秒又不得不新建40个连接来弥补连接的不足。
  • 再来一次类似的场景,假设请求是均匀的,而应答不再均匀,前10毫秒只有50个请求结束,后10毫秒有150个:


  • 前10毫秒,进来100个请求,结束50个请求,导致连接不够用,nginx为此新建50个连接
  • 后10毫秒,进来100个请求,结束150个请求,导致空闲连接过多,ngixn为此关闭了150-100-10=40个空闲连接


  • 第二个应答不均匀的场景实际上是对应第一个请求不均匀的场景:正是因为请求不均匀,所以导致100毫秒之后这些请求的应答必然不均匀


现实世界中的请求往往和理想状态有巨大差异,请求不均匀,服务器处理请求的时间也不平稳,这理论上的大概1000个连接在反复的回收和再分配的过程中,必然出现两种非常矛盾场景在短时间内反复:


  1. 连接不够用,造成新建连接
  2. 连接空闲,造成关闭连接。从而使得总连接数出现反复震荡,不断的创建新连接和关闭连接,使得长连接的效果被大大削弱。



Keepalive参数建议


造成连接数量反复震荡的一个推手,就是这个keepalive 这个最大空闲连接数。毕竟连接池中的1000个连接在频繁利用时,出现短时间内多余10个空闲连接的概率实在太高。因此为了避免出现上面的连接震荡,必须考虑加大这个参数,比如上面的场景如果将keepalive设置为100或者200,就可以非常有效的缓冲请求和应答不均匀




keepalive参数分析


  • 对应的参数设置为每个worker子进程在缓冲中保持的到upstream服务器的空闲keepalive连接的最大数量。当超过这个数量值的时候,会将最近最少使用(LRU)的连接进行关闭。需要考虑的是keepalive指令不会限制一个worker进程到upstream服务器连接的总数量。其参数应该设置为一个足够小的数字来让upstream服务器来处理新进来的连接。


  • 如果想让upstream每次都处理新的进来的连接,就应该将这个值放的足够小。反过来理解,就是如果不想让upstream服务器处理新连接,就应该放大一些?




Keepalive的使用案例


Keepalive对接memcached服务


使用keepalive连接的memcached upstream配置的例子:

upstream memcached_backend {
    server 127.0.0.1:11211;
    server 10.0.0.2:11211;
    keepalive 32;
}
server {
    ...
    location /memcached/ {
        set $memcached_key $uri;
        memcached_pass memcached_backend;
    }
}
复制代码



Keepalive对接Http1.1的Web服务

对于HTTP,proxy_http_version指定应该设置为”1.1”,而”Connection” header应该被清理:

upstream http_backend {
    server 127.0.0.1:8080;
    keepalive 16;
}
server {
    ...
    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}
复制代码



Keepalive对接Http1.0的Web服务

HTTP/1.0 持久连接可以通过传递”Connection: Keep-Alive” header 到upstream server, 但是不推荐使用这种方法。



Keepalive对接FastCGI的Web服务

对于FastCGI服务器,要求设置fastcgi_keep_conn来让长连接工作:

upstream fastcgi_backend {
    server 127.0.0.1:9000;
    keepalive 8;
}
server {
    ...
    location /fastcgi/ {
        fastcgi_pass fastcgi_backend;
        fastcgi_keep_conn on;
        ...
    }
}
复制代码

当使用默认的round-robin之外的负载均衡算法时,必须在keepalive指令之前激活他们。SCGI 和 uwsgi 协议没有keepalive连接的概念。




保持和client的长连接


为了在client和nginx之间保持上连接,有两个要求:

  • client发送的HTTP请求要求keep alive
  • nginx设置上支持keep alive



HTTP配置


默认情况下,Nginx已经自动开启了对client连接的keep alive支持。一般场景可以直接使用,但是对于一些比较特殊的场景,还是有必要调整个别参数。需要修改nginx的配置文件(在nginx安装目录下的conf/nginx.conf):

http {
    keepalive_timeout  120s 120s;
    keepalive_requests 10000;
}
复制代码



keepalive_timeout指令

keepalive_timeout指令的语法:

Syntax:    keepalive_timeout timeout [header_timeout];
Default:    keepalive_timeout 75s;
Context:    http, server, location
复制代码



  1. 第一个参数设置keep-alive客户端连接在服务器端保持开启的超时值。值为0会禁用keep-alive客户端连接。


  1. 可选的第二个参数在响应的header域中设置一个值“Keep-Alive: timeout=time”。这两个参数可以不一样。


注:默认75s一般情况下也够用,对于一些请求比较大的内部服务器通讯的场景,适当加大为120s或者300s。第二个参数通常可以不用设置




keepalive_requests指令

keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量。当最大请求数量达到时,连接被关闭。默认是100。


keepalive_requests指令的实现原理


  • 指一个keepalive请求建立之后,Nginx就会为这个连接设置一个计数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则Nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接。


这个参数往往被大多数人忽略,因为大多数情况下当QPS(每秒请求数)不是很高时,默认值100凑合够用。但是,对于一些QPS比较高(比如超过10000QPS,甚至达到30000,50000甚至更高) 的场景,默认的100就显得太低


  • 简单计算一下,QPS=10000时,客户端每秒发送10000个请求(通常建立有多个长连接),每个连接只能最多跑100次请求,意味着平均每秒钟就会有100个长连接因此被nginx关闭
  • 为了保持QPS,客户端不得不每秒中重新新建100个连接。因此,如果用netstat命令看客户端机器,就会发现有大量的TIME_WAIT的socket连接(即使此时keep alive已经在client和nginx之间生效)。


因此对于QPS较高的场景,非常有必要加大这个参数,以避免出现大量连接被生成再抛弃的情况,减少TIME_WAIT




保持和server的长连接


为了让Nginx和server(Nginx称为upstream)之间保持长连接,典型设置如下:

http {
    upstream  BACKEND {
        server   192.168.0.1:8080  weight=1 max_fails=2 fail_timeout=30s;
        server   192.168.0.2:8080  weight=1 max_fails=2 fail_timeout=30s;
        keepalive 300;        // 这个很重要!
    }
    server {
        listen 8080 default_server;
        server_name "";
        location /  {
            proxy_pass http://BACKEND;
            proxy_set_header Host  $Host;
            proxy_set_header x-forwarded-for $remote_addr;
            proxy_set_header X-Real-IP $remote_addr;
            add_header Cache-Control no-store;
            add_header Pragma  no-cache;
            proxy_http_version 1.1;                    // 这两个最好也设置
            proxy_set_header Connection "";
            client_max_body_size  3072k;
            client_body_buffer_size 128k;
        }
    }
}
复制代码

总结

image.png

  • keepalive 这个参数一定要小心设置,尤其对于QPS比较高的场景,推荐先做一下估算,根据QPS和平均响应时间大体能计算出需要的长连接的数量。比如前面10000 QPS和100毫秒响应时间就可以推算出需要的长连接数量大概是1000. 然后将keepalive设置为这个长连接数量的10%到30%。
  • 如果不喜欢计算的同学也可以直接设置为keepalive=1000之类的,一般都OK的了。



相关文章
|
2月前
|
负载均衡 监控 应用服务中间件
配置Nginx反向代理时如何指定后端服务器的权重?
配置Nginx反向代理时如何指定后端服务器的权重?
159 61
|
18天前
|
存储 弹性计算 安全
阿里云服务器配置选择策略参考及后期使用注意事项
对于初次购买阿里云服务器的一些新手用户来说,在云服务器配置选择和后期使用过程中有一些不清楚的地方,小编分享几点阿里云服务器配置选择策略,以及后期使用注意事项,购买过程中注意好下面这些事项,能让我们选对选好阿里云服务器,购买之后,在使用过程中,注意下面这些事项,能够让我们更好、更安全的使用阿里云服务器。下面是小编分享的一份详尽的阿里云服务器配置与使用指南,以供参考和借鉴。
|
2月前
|
安全 Linux 应用服务中间件
从零开始启动、配置、保护你的云服务器并搭建一个简单的网站
本文详细介绍了如何准备原料、搭建基础环境、进行安全防护、建设网站、管理证书以及开启BBR优化网络性能。主要内容包括获取健康云服务器、配置SSH登录、创建非root用户、启用密钥认证、安装Nginx、申请TLS证书、配置HTTPS自动跳转及优化网络性能等步骤。通过本文,读者可以掌握从零开始搭建个人网站的全过程。
53 2
从零开始启动、配置、保护你的云服务器并搭建一个简单的网站
|
1月前
|
存储 监控 调度
云服务器成本优化深度解析与实战案例
本文深入探讨了云服务器成本优化的策略与实践,涵盖基本原则、具体策略及案例分析。基本原则包括以实际需求为导向、动态调整资源、成本控制为核心。具体策略涉及选择合适计费模式、优化资源配置、存储与网络配置、实施资源监控与审计、应用性能优化、利用优惠政策及考虑多云策略。文章还通过电商、制造企业和初创团队的实际案例,展示了云服务器成本优化的有效性,最后展望了未来的发展趋势,包括智能化优化、多云管理和绿色节能。
|
1月前
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
1月前
|
存储 编解码 应用服务中间件
使用Nginx搭建流媒体服务器
本文介绍了流媒体服务器的特性及各种流媒体传输协议的适用场景,并详细阐述了使用 nginx-http-flv-module 扩展Nginx作为流媒体服务器的详细步骤,并提供了在VLC,flv.js,hls.js下的流媒体拉流播放示例。
174 1
|
2月前
|
存储 人工智能 弹性计算
阿里云弹性计算(ECS)提供强大的AI工作负载平台,支持灵活的资源配置与高性能计算,适用于AI训练与推理
阿里云弹性计算(ECS)提供强大的AI工作负载平台,支持灵活的资源配置与高性能计算,适用于AI训练与推理。通过合理优化资源分配、利用自动伸缩及高效数据管理,ECS能显著提升AI系统的性能与效率,降低运营成本,助力科研与企业用户在AI领域取得突破。
68 6
|
2月前
|
存储 分布式计算 固态存储
阿里云2核16G、4核32G、8核64G配置云服务器租用收费标准与活动价格参考
2核16G、8核64G、4核32G配置的云服务器处理器与内存比为1:8,这种配比的云服务器一般适用于数据分析与挖掘,Hadoop、Spark集群和数据库,缓存等内存密集型场景,因此,多为企业级用户选择。目前2核16G配置按量收费最低收费标准为0.54元/小时,按月租用标准收费标准为260.44元/1个月。4核32G配置的阿里云服务器按量收费标准最低为1.08元/小时,按月租用标准收费标准为520.88元/1个月。8核64G配置的阿里云服务器按量收费标准最低为2.17元/小时,按月租用标准收费标准为1041.77元/1个月。本文介绍这些配置的最新租用收费标准与活动价格情况,以供参考。
|
2月前
|
监控 PHP Apache
优化 PHP-FPM 参数配置:实现服务器性能提升
优化PHP-FPM的参数配置可以显著提高服务器的性能和稳定性。通过合理设置 `pm.max_children`、`pm.start_servers`、`pm.min_spare_servers`、`pm.max_spare_servers`和 `pm.max_requests`等参数,并结合监控和调优措施,可以有效应对高并发和负载波动,确保Web应用程序的高效运行。希望本文提供的优化建议和配置示例能够帮助您实现服务器性能的提升。
99 3
|
2月前
|
存储 缓存 固态存储
阿里云服务器2核8G、4核16G、8核32G配置租用收费标准与活动价格参考
2核8G、8核32G、4核16G配置的云服务器处理器与内存比为1:4,这种配比的云服务器一般适用于中小型数据库系统、缓存、搜索集群和企业办公类应用等通用型场景,因此,多为企业级用户选择。本文介绍这些配置的最新租用收费标准与活动价格情况,以供参考。