Nginx特性之Keepalive连接保持

Nginx关于keepalive连接保持的特性,实际上就是在一次TCP连接中,可以持续处理多个客户请求,而不断开连接。通过该机制可以减少TCP连接的建立次数,减少TIME_WAIT的状态连接。从而增加服务的吞吐量和整体服务质量。但是,长时间的TCP连接会导致系统资源被长时间占用,浪费资源,所以在实际使用的时候,还需要为keepalive设置合理的 timeout

timeout的含义

  • 1.在keepalive_timeout时间内,若有新的请求进来,使用了该连接,timeout时间将会被刷新,重新计数
  • 2.在keepalive_timeout时间内,若一直没有新的请求,一直处理空闲状态,则在超时后,nginx会主动断开该连接。在发送第一个FIN包后,该连接将不能再被使用
Http Keepalive和Tcp Keepalive的差异

Http Keepalive是为了复用TCP连接,让其在空闲状态能够再存在一段时间,服务于后续的用户请求。Tcp Keepalive是操作系统内核检测TCP连接状态的一种保鲜机制,两者是不同的东西。

个人理解:http是请求,tcp是载体,请求装入载体,发送到服务器,服务器内核监听到tcp连接,把其中的请求转发到对应端口直到响应回去。通过复用载体,减少握手次数,来提示性能

查看 linux 系统内核 TCP 的默认参数设置: sysctl -a|grep tcp_keepalive

  net.ipv4.tcp_keepalive_intvl = 75
  net.ipv4.tcp_keepalive_probes = 9
  net.ipv4.tcp_keepalive_time = 7200

当TCP连接处于空闲状态时,当空闲时间超过tcp_keepalive_time后,服务器内核会尝试向client发送侦测包,来判断该链接的状态(可能存在客户端异常崩溃、网络异常等情况)。如果没有收到客户端的ACK确认报文,内核会在tcp_keepalive_intvl时间后再次尝试侦测。如果侦测tcp_keepalive_probes次后,依然没有收到client的响应,则会认为该连接已经不可用,内核选择丢弃该TCP连接。

操作系统默认的tcp_keepalive_time为2小时,一般生产环境会设置为30分钟

keepalive复用tcp连接

复用tcp连接的优点:
1.减少握手次数
2.减少并发连接数,减少了服务器资源的消耗
3.降低TCP拥塞控制的影响

分两步使用keepalive:1.对客户端使用 keepalive,2.对上游服务使用 keepalive

# nginx 使用 keepalive 的配置
http{
  
  upstream zy {
    server 127.0.0.1:8011;
    server 127.0.0.1:8012;
    
    #对上游服务使用keepalive,并缓存32个连接
    keepalive 32;
    #在一个tcp连接上,最多执行多少个http请求,默认值100
    keepalive_requests 100;
    #一个http请求完成后,最多经过timeout时间,如果还没有新的请求就关闭连接,默认值60
    keepalive_timeout 45s;
  }

  server {
    #对客户端keepalive-tcp探活,30分钟后无数据会发送探活包,时间间隔使用系统默认的,发送10次探活包
    listen 80 so_keepalive=30m::10;
    server_name zy.csxiuneng.com;
    location /{
      proxy_pass http://zy;
      #使用keepalive必须使用下面两个指令,因为只有http1.1协议才支持keepalive,http1.0是不支持的
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;
      #client_max_body_size 10m;
      #client_body_buffer_size 256k;
      #proxy_connect_timeout 90;
      #proxy_send_timeout 90;
      #proxy_buffer_size 4k;
      #proxy_buffers 4 32k;
      #proxy_busy_buffers_size 64k;
      #proxy_temp_file_write_size 64k;
    }
  }
}
测试

使用 jmeter 并发测试,可以看到开启keepalive后的请求所用时间小于未开启状态的,从而增加服务的吞吐量和整体服务质量
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐