首页 > Web开发 > 详细

Nginx配置不当导致http1.1长连接未生效

时间:2020-01-10 00:56:46      阅读:864      评论:0      收藏:0      [点我收藏+]

http1.1中引入了keep-alive机制,使得http协议连接能够延迟关闭,进行复用,能够进行一次3挥手,而完成多次进行通信。

更为重要的是下面问题中的一种场景:减少打开关闭连接次数,显著减少处于time_wait的TCP连接数,提高瞬时系统并发能力。

实验方法:

一共进行3次不同的实验

1、client -> springboot rest service

2、client -> nginx -> springboot rest service

3、client -> nginx(优化配置) -> springboot rest service

client代码:

        for(int i=0; i<1001; i++) {
            try {
            StringEntity entity = new StringEntity(JSON.toJSONString(map));
            String response = Request.Post(url_nginx).connectTimeout(5000).socketTimeout(5000).addHeader
                    ("Content-Type", "application/json").body(entity).execute().returnContent().asString();
            Thread.sleep(1);
            }catch(Exception e) {
            }
        }

nginx配置(优化前):

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  ‘$remote_addr - $remote_user [$time_local] "$request" ‘
    #                  ‘$status $body_bytes_sent "$http_referer" ‘
    #                  ‘"$http_user_agent" "$http_x_forwarded_for"‘;

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
server {
        listen       8089;
        server_name  gateway;
        location / {
            proxy_pass http://127.0.0.1:8081;
        }
    }
}

springboot rest service:就一个非常普通的RestController

@RestController
@RequestMapping(value = "system", method = RequestMethod.POST)public class SystemController {
    private static final Logger LOGGER = LoggerFactory.getLogger(SystemController.class);
@RequestMapping("testGateway") public Response testGateway(@RequestBody ClientRequest clientRequest, HttpServletRequest request ) { long start = System.nanoTime(); Response rd = new Response(); ErrorCode result = ErrorCode.OK; rd.setErrorCode(result.value); rd.setValue(result.memo); long time = System.nanoTime() - start; //LOGGER.info("time:" + time); return rd; } }

 

结论: 通过client直接调用springboot或者是client调用nginx(配置优化)转发调用springboot,由于每段调用都采用了http1.1连接复用与池化技术,产生的time_wait非常少,占用TCP连接资源非常小。

技术分享图片

 

 但是,如果是client调用nginx(未配置优化)转发调用springboot,由于client调用nginx是http1.1而nginx转发调用springboot这时候用的是http1.0,则造成后一段调用每次都会打开-关闭一个tcp连接,生成大量time_wait状态的TCP连接,造成瞬时资源紧张,系统并发能力堪忧。

技术分享图片

技术分享图片

 

一般的,TIME_WAIT状态的TCP连接会默认保持4分钟(笔者的windows笔记本由于修改过注册表,tcp只保持30秒,但对于生产服务器来说,优先不应该去改这个参数),我们假设服务器可打开的TCP最大为5000,通过计算也就是说最大并发仅为20 QPS!!!因为240秒之内就已经产生了20*240=4800个time_wait状态的TCP连接了!而就算是笔者公司的云服务器,最大可打开65535个TCP,那么最大并发也不过才273 QPS而已,对于一个互联网应用来说根本不够看!

 最后附上优化后的nginx配置:

    upstream gateway {
        server 127.0.0.1:8081;
        keepalive 10;
        keepalive_requests 30000;
        keepalive_timeout 30s;    #nginx version 1.15.3以上才有
    }
    server {
        listen       8088;
        server_name  localhost;

        location / {
            proxy_pass http://gateway;
            proxy_http_version  1.1;
            proxy_set_header    Connection "";
        }
    }

 

Nginx配置不当导致http1.1长连接未生效

原文:https://www.cnblogs.com/lyhero11/p/12173838.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!