怎么把单机的高并发做到最高,为什么 1 万的并发和 5 万的并发, CPU 占用没有变化? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
goforwardv2
V2EX    程序员

怎么把单机的高并发做到最高,为什么 1 万的并发和 5 万的并发, CPU 占用没有变化?

< href="Javascript:" Onclick="upVoteTopic(1045692);" class="vote">
  •  
  •   goforwardv2 2024-05-31 14:38:44 +08:00 2817 次点击
    这是一个创建于 532 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近基于开源的高性能网络库 muduo/libhv ,分别搭建一个简单的 HTTP 服务器,就一个接口/get ,然后返回 hello world. HTTP 服务器单独部署在 8 核的 ubuntu 机器上,代码中开了 8 个工作线程。

    在另一台 12 核的 ubuntu 机器上用 wrk 对 HTTP 服务器进行压测。两台机器都分别用ulimit -n 65536开启了最大的连接数。

    HTTP 服务器还做了一些内核参数的优化,在/etc/sysctl.conf 里面加入了如下内容:
    net.ipv4.tcp_keepalive_time = 1200
    net.ipv4.ip_local_port_range = 10000 65000
    net.ipv4.tcp_max_syn_backlog = 8192
    net.ipv4.tcp_max_tw_buckets = 5000
    net.ipv4.tcp_max_syn_backlog = 65536
    net.core.netdev_max_backlog = 32768
    net.core.somaxcOnn= 32768
    net.core.wmem_default = 8388608
    net.core.rmem_default = 8388608
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216
    net.ipv4.tcp_synack_retries = 2
    net.ipv4.tcp_syn_retries = 2
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_wmem = 8192 436600 873200
    net.ipv4.tcp_rmem = 32768 436600 873200
    net.ipv4.tcp_mem = 94500000 91500000 92700000
    net.ipv4.tcp_max_orphans = 3276800
    net.ipv4.tcp_fin_timeout = 30

    但发现有几个现象不是很理解:

    1. wrk 同时开启的客户端越少,得到的 QPS 数据越好,以下是具体数据

    `alex@alex-System-Product-Name:~/code/wrk$ wrk -t12 -c1000 -d100s
    12 threads and 1000 connections
    Thread Stats Avg Stdev Max +/- Stdev
    Latency 41.01ms 37.09ms 542.37ms 88.01%
    Req/Sec 2.38k 1.11k 8.33k 62.50%
    2838582 requests in 1.67m, 319.44MB read
    Requests/sec: 28358.09
    Transfer/sec: 3.19MB

    alex@alex-System-Product-Name:~/code/wrk$ wrk -t12 -c10000 -d100s
    12 threads and 10000 connections
    Thread Stats Avg Stdev Max +/- Stdev
    Latency 364.67ms 115.01ms 1.49s 81.21%
    Req/Sec 2.04k 0.98k 7.46k 61.89%
    2430692 requests in 1.67m, 273.53MB read
    Socket errors: connect 0, read 0, write 0, timeout 93
    Requests/sec: 24292.02
    Transfer/sec: 2.73MB

    alex@alex-System-Product-Name:~/code/wrk$ wrk -t36 -c50000 -d60s
    36 threads and 50000 connections
    Thread Stats Avg Stdev Max +/- Stdev
    Latency 910.52ms 276.46ms 2.00s 83.81%
    Req/Sec 836.26 0.90k 13.56k 86.67%
    1489770 requests in 1.00m, 167.65MB read
    Socket errors: connect 21740, read 0, write 0, timeout 16523
    Requests/sec: 24790.08
    Transfer/sec: 2.79MB
    `

    2. 不管以上那种压测的方式,HTTP 服务器的 CPU 占用都稳定在 240%左右,一核 30%左右,等于没有系统的 CPU 利用一点都不高,没有完全压榨机器的 CPU 性能,按道理并发数不同,服务器的压力应该也不同。

    3. 当在压测服务器之间和 HTTP 服务器之间,用另一台 8 和的机器搭建 Nginx 做代理,然后 wrk 直接向 Nginx 请求,Nginx 再转发,发现没有直接法相 HTTP 服务器得到的 QPS 高,Nginx 的作用难道不是替后端服务抵挡高并发吗,怎么加了,效果变差了。Nginx 的配置也加入了:

    worker_processes auto; worker_rlimit_nofile 30000; events { worker_connections 10240; }

    第 1 条附言    2024-05-31 17:22:13 +08:00
    确实是测试机的个关系,换了一台 24 核(Intel(R) Core(TM) i9),用:
    hey -n 1000000 -c 1000 http://172.16.15.9:8090/get 测试,结果如下:
    Summary:
    Total: 6.2846 secs
    Slowest: 0.0940 secs
    Fastest: 0.0001 secs
    Average: 0.0062 secs
    Requests/sec: 159119.5821

    然后 HTTP 服务器的 CPU 占用率也提高到了 400%,看来压测工具想真正模拟高并发,需要机器的性能比较好。
    13 条回复    2024-05-31 18:03:18 +08:00
    lsk569937453
        1
    lsk569937453  
       2024-05-31 15:01:22 +08:00
    1.换压测工具试试,https://github.com/rakyll/hey
    2.或者可以换 echo-server,https://github.com/lsk569937453/echo-server 。我的这个 echo-server ,4core 8g 的机器压测结果如下:
    hey -n 1000000 -c 1000 http://backend:8080

    Summary:
    Total: 4.2522 secs
    Slowest: 0.2671 secs
    Fastest: 0.0000 secs
    Average: 0.0041 secs
    Requests/sec: 235174.6871

    Total data: 1000000 bytes
    Size/request: 1 bytes


    3.让我猜测的话,我更倾向于压测机器(wrk 执行命令的机器)的性能达到了瓶颈。
    goforwardv2
        2
    goforwardv2  
    OP
       2024-05-31 15:02:45 +08:00
    @lsk569937453 多谢,我试下
    shakeyo
        3
    shakeyo  
       2024-05-31 15:03:31 +08:00
    1 是因为服务端线程太少客户端连接数太多,很多都耗在连接跟响应等待了
    2 应该是跟 muduo/libhv 的模型有关,也跟你 8 个线程数设定有关,加大线程池肯定可以提高
    3nginx 作为代理,等于多了一次连接,这都需要时间

    菜鸡的浅薄理解,蹲一个大佬
    lsk569937453
        4
    lsk569937453  
       2024-05-31 15:08:43 +08:00
    @lsk569937453 压测的时候还有一个问题是不可忽视的,就是网络延迟。最好看一下两台机器的网络延迟是多少。高性能的 echo-server 的 TPS 不会很低的。

    你在压测的机器前面加了一层 Nginx 的转发,QPS 变低是必然的,Nginx 至少降低 10%的性能。Nginx 的作用是负载均衡。请求在经过 Nginx 的时候,Nginx 需要解析请求的 header 并且中间多了一层网络转发。
    ppking
        5
    ppking  
       2024-05-31 15:16:46 +08:00
    cpu 上不去,说明瓶颈在 IO 呗
    sagaxu
        6
    sagaxu  
       2024-05-31 15:19:04 +08:00
    高并发请求和高并发连接数是不同的概念,nginx 能解决高并发连接数,对单服务器的高并发请求没有任何帮助。
    yzongyue
        7
    yzongyue  
       2024-05-31 15:54:55 +08:00
    试试 nginx 后面挂 8 个 http server , 每个 server 只起一个工作线程,这样 cpu 能不能上去
    F7TsdQL45E0jmoiG
        8
    F7TsdQL45E0jmoiG  
       2024-05-31 16:01:35 +08:00
    I/O 密集型
    goforwardv2
        9
    goforwardv2  
    OP
       2024-05-31 16:07:54 +08:00
    @ppking @morenacl 每个链接只传输 1 字节的负载,内核参数该优化的也都优化,难道 8 核 1000M 网卡的机器的极限就是 4~5 万 QPS 吗
    F7TsdQL45E0jmoiG
        10
    F7TsdQL45E0jmoiG  
       2024-05-31 17:05:29 +08:00
    @goforwardv2 类似服务器跑 nginx ,极简 http get ,极限 qps 大概 8-10w qps 。有必要自己搭 http 服务吗?另外,增大内存有助于提高 qps
    goforwardv2
        11
    goforwardv2  
    OP
       2024-05-31 17:31:00 +08:00
    @morenacl 不是为了搭建 http 服务器用,纯纯是为了
    1. 验证几个网络库的性能(其实主要的使用场景是 TCP 长连接,但压测 TCP 比较麻烦)
    2. 看下在确定网络库的情况下,调整哪些系统的网络参数,可以让机器承载更多的高并发
    3. 看下固定配置的机器到底能抗住多少量级的高并发
    我那个极简的 HTTP Server ,高并发跑起来,内存占用都不到 1%,然后没有任何的磁盘 IO 操作,网卡性能和带宽也可以。
    ppking
        12
    ppking  
       2024-05-31 18:00:58 +08:00
    把工作线程数开多点啊,你都说了平均到单核 30%多的 cpu 使用率,说明大部分时间在等 io 呗。
    ppking
        13
    ppking  
       2024-05-31 18:03:18 +08:00
    你 cpu 使用率上不去,是用%u+%s 合在一起只有 30%多嘛? cpu 的大部分时间片在等 IO ,那你就多开点线程呗,交给操作系统去调度,8 核的服务器不意味着就开 8 个工作线程。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5226 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 08:59 PVG 16:59 LAX 00:59 JFK 03:59
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86