美文网首页
nginx挂两个api,qps真的能翻倍吗?

nginx挂两个api,qps真的能翻倍吗?

作者: coder爱唱歌 | 来源:发表于2020-07-27 00:49 被阅读0次

    最近为了提升接口qps,想了很多办法,当接口在单机上qps已经达到了极限,很容易想到的就是部署多个api,通过nginx去转发,达到qps翻倍的目的。
    但是qps真的能翻倍吗?我用nginx挂两个api,测试了多个接口,发现有的能翻倍,有的qps只能多百分之20,有的qps甚至下降了。
    在网上搜索了很多,都说能翻倍,我当时就懵逼了。于是乎就做了以下实验。

    实验目的

    • 验证nginx挂两个api,aps真的能翻倍吗?

    测试机器以及应用部署情况

    • 内网8核16g(放wrk)
    • 内网8核16g(放nginx)
    • 内网8核16g (放api1)
    • 内网8核心16g(放api2)

    测试工具

    wrk

    测试脚本

    ./wrk -t16 -c400 -d30s -s test-nginx.lua --latency  http://192.168.40.92:9000/test/testNginx
    ./wrk -t16 -c400 -d30s -s test-nginx.lua --latency  http://192.168.40.93:9000/test/testNginx
    ./wrk -t16 -c400 -d30s -s test-nginx.lua --latency  http://192.168.40.91/test/testNgin
    

    备注:第一个和第二个是单独对两个api的测试。第三个是对nginx机器分发两台api的测试

    test-nginx.lua

    wrk.method = "POST"
    wrk.headers["Content-Type"] = "application/json"
    wrk.body   = "{\"sleep\": 1000}"
    

    nginx配置

    upstream test-nginx {
           server 192.168.40.92:9000 weight=1 ;
           server 192.168.40.93:9000 weight=1;
    }
    server {
        listen       80;
        server_name  localhost;
        location / {
            proxy_pass http://test-nginx;
            proxy_http_version 1.1;
            proxy_redirect    off;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  Host $host;
        }       
    }
    

    测试代码

    @RestController
    @RequestMapping("/test/")
    public class TestController {
        @PostMapping("/testNginx")
        public Response<String> getTest(@Valid @RequestBody TestNginxReq req) {
            try {
                Thread.sleep(req.getSleep());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Response.ok("test nginx");
        }
    }
    

    请求示例

    {
        "sleep": 100
    }
    

    返回示例

    {
        "code": "200",
        "msg": "OK",
        "body": "test nginx"
    }
    

    接口说明:接口啥都没做,就是传入一个sleep参数,然后程序就sleep多长时间。目的是为了通过sleep参数能稳定控制住接口的qps。所以本次实验变量就是单个接口qps,然后讨论接口qpsnginx挂多个api是否能做到qps翻倍的问题。

    实验结果

    序号 sleep参数 api1的qps qpi2的qps 通过nginx转两个api的qps
    1 200 158.12/s 158.60/s 317.29/s
    2 70 453.59/s 453.77/s 905.48/s
    3 2 9367.26/s 9335.16/s 12294.76/s
    4 0 18829.48/s 18776.76/s 12408.13/s

    实验结果分析

    • 1.首先看1,2,3,4实验,当参数相同的时候,api1和api2的qps是一致的,说明两台机器上的api比较稳定。
    • 2.对比1,2号实验,发现当api的qps不高时,nginx转发两台qps翻倍了。
    • 3.查看3号实验,单个qps是9000多,理论上转发两个是18000,但是nginx转2台是12294.76/s。查看实验四更离谱,单个api是18000/s,nginx转两台还是 12408.13/s,这里nginx转发两台api的qps甚至比单个api的性能还低。
      • 分析一下,12000多大概是nginx的瓶颈,所以api如果继续增大qps,那么,转发两台还是12000多(对nginx做优化不在本次讨论范围)。

    实验结论

    • 当api比较慢的时候,qps比较低,使用nginx转发,的确能够达到翻倍的效果。这时候瓶颈在api。
    • 当api很快的时候,nginx转发不能翻倍,甚至会下滑,因为瓶颈不在api,而在于nginx或者网络。(nginx转发是多了网络开销)
    • 所以单个接口qps到达一个平衡值,通过nginx刚好能翻倍,然后单个api的qps继续增加,通过nginx转发就达不到翻倍效果了。

    访问链路分析

    首先看两张图


    直接访问api流程.png
    访问nginx流程.png

    查看上面两张图,有以下已知的内容:

    • 1.api的耗时两张图中是相等的
    • 2.直接访问api两次网络请求,网络传输包中一次带请求参数(t1),一次带接口返回接口(t3),而访问nginx有4个网络请求,网络传输包中两次带请求参数(t1,t2),两次带返回参数(t6,t7)。所以,通过nginx访问的网络传输耗时是直接访问api的两倍(注意:网络耗时很短,这里两倍其实并不多)
    • 3.除了两倍的网络以外,访问nginx还比直接访问api多了nginx处理的耗时。(nginx性能很高,这里时间也很短)
    • 4.总结上面2和3,就是访问nginx比直接访问api多了两倍网络耗时和一次nginx处理耗时。

    基于上面已知条件,有以下结论:

    • 1.nginx挂单个api的qps肯定比单个api的qps要低。
    • 2.当api很慢,主要耗时在于api处理耗时,nginx多的那些时间可以忽略不计,所以这时,挂多个api能翻倍。
      1. 当api处理耗时比较短,那么nginx多出来的两次网络传输时间和自身处理时间就不可以忽略了,就会出现,不能翻倍,只会达到增加20%,30%这种情况。
    • 4.当api处理时间非常短,几乎和nginx处理耗时相当了,那么不管挂多少个api,都会多出那几次的网络请求耗时和nginx处理耗时,挂多个api的qps肯定也不如一个api的qps。

    相关文章

      网友评论

          本文标题:nginx挂两个api,qps真的能翻倍吗?

          本文链接:https://www.haomeiwen.com/subject/nennlktx.html