V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
q937298063
V2EX  ›  Linux

[求助] nginx 服务器在并发达到 300 就出现响应慢,甚至到 8 秒的情况

  •  
  •   q937298063 · 2019-05-27 16:29:19 +08:00 · 6714 次点击
    这是一个创建于 2025 天前的主题,其中的信息可能已经有所发展或是发生改变。
    服务器版本:centos
    服务器配置:阿里云实例规格:ecs.c5.large 2 核 4G
    服务器环境:nginx 1.14.1 + php 5.6.36 + mysql 5.7.22

    问题描述:在并发量在 300 的时候,不知道为什么响应时间特别长 达到了 8 秒甚至 10 秒以上

    测试描述: 使用 apache 的 ab 压力测试工具 测试网站的页面,这个页面什么也没有就是单纯的用 php return 了一个 json 字符串。使用的命令是.\abs -c 300 -n 500 地址

    测试结果
    Server Port: 443
    SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256

    Document Path: /
    Document Length: 166 bytes

    Concurrency Level: 300
    Time taken for tests: 12.325 seconds
    Complete requests: 500
    Failed requests: 257
    (Connect: 0, Receive: 0, Length: 257, Exceptions: 0)
    Non-2xx responses: 243
    Total transferred: 124917 bytes
    HTML transferred: 47791 bytes
    Requests per second: 40.57 [#/sec] (mean)
    Time per request: 7395.060 [ms] (mean)
    Time per request: 24.650 [ms] (mean, across all concurrent requests)
    Transfer rate: 9.90 [Kbytes/sec] received

    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 557 1737 783.3 1517 3500
    Processing: 30 2514 2053.8 1862 6267
    Waiting: 28 2360 2152.5 1711 6267
    Total: 1248 4251 2325.3 5031 8428

    Percentage of the requests served within a certain time (ms)
    50% 5031
    66% 5784
    75% 6284
    80% 6574
    90% 7450
    95% 7755
    98% 8107
    99% 8338
    100% 8428 (longest request)


    配置信息:
    nginx.conf

    user www www;

    worker_processes auto;

    error_log /home/wwwlogs/nginx_error.log crit;

    pid /usr/local/nginx/logs/nginx.pid;

    #Specifies the value for maximum file descriptors that can be opened by this process.
    worker_rlimit_nofile 51200;

    events
    {
    use epoll;
    worker_connections 51200;
    accept_mutex off;
    multi_accept on;
    }

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

    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 50m;

    sendfile on;
    tcp_nopush on;

    keepalive_timeout 0;

    tcp_nodelay on;

    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 256k;

    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 2;
    gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss;
    gzip_vary on;
    gzip_proxied expired no-cache no-store private auth;
    gzip_disable "MSIE [1-6]\.";

    #limit_conn_zone $binary_remote_addr zone=perip:10m;
    ##If enable limit_conn_zone,add "limit_conn perip 10;" to server section.

    server_tokens off;
    access_log off;
    }


    php-fpm.conf

    [global]
    pid = /usr/local/php/var/run/php-fpm.pid
    error_log = /home/wwwlogs/php-fpm.log
    log_level = notice

    [www]
    listen = /tmp/php-cgi.sock
    listen.backlog = -1
    listen.allowed_clients = 127.0.0.1
    listen.owner = www
    listen.group = www
    listen.mode = 0666
    user = www
    group = www
    pm = static
    pm.max_children = 32
    pm.start_servers = 30
    pm.min_spare_servers = 30
    pm.max_spare_servers = 200
    request_terminate_timeout = 100
    request_slowlog_timeout = 0
    slowlog = var/log/slow.log
    43 条回复    2019-05-31 18:02:04 +08:00
    tankerwng
        1
    tankerwng  
       2019-05-27 16:33:31 +08:00
    没 log 没真相,请展示 error.log 。
    rockivy
        2
    rockivy  
       2019-05-27 16:34:59 +08:00
    ab 压测要带上-k 参数,开启 keepalive 特性。
    q937298063
        3
    q937298063  
    OP
       2019-05-27 16:35:42 +08:00
    nginx 没有报错 php-fpm 也木有报错。。。。。我也是很绝望
    q937298063
        4
    q937298063  
    OP
       2019-05-27 16:36:22 +08:00
    @rockivy 好的 我测试一下 多谢
    q937298063
        5
    q937298063  
    OP
       2019-05-27 16:38:17 +08:00
    @rockivy 老哥 我带上-k 的测试效果 还是这样 我是这样输入的 .\abs -k -c 300 -n 500 地址
    azh7138m
        6
    azh7138m  
       2019-05-27 16:40:05 +08:00
    为啥提到了 MySQL,是去数据库查询数据然后返回吗?
    q937298063
        7
    q937298063  
    OP
       2019-05-27 16:44:07 +08:00
    @azh7138m 木有 只是怕没说明白。顺带说一下,因为我先从线上环境里发现这个问题的。一开始我认为是我写的 sql 语句有问题,最后查看了日志。一次接口调用 sql 时用的时间不超过 0.5 秒所以排除了。目前我从网上资料查询过来,都是说 nginx 和 php-fpm 之间的问题。可是我尝试的修改 php-fpm 的数量依旧没有任何效果。
    Citrus
        8
    Citrus  
       2019-05-27 16:58:18 +08:00
    压测期间 CPU 内存情况呢?
    q937298063
        9
    q937298063  
    OP
       2019-05-27 16:59:59 +08:00
    @Citrus 测试期间的话 cpu 最高达到 56%左右 并没有爆。。。
    asilin
        10
    asilin  
       2019-05-27 17:00:29 +08:00
    排除法:
    1. 测试 nginx 服务本身,放一个静态页面 index.html 压测,得到 nginx 和外网带宽的最大 QPS ;
    2. 开启 FPM 服务进行压测,此时的 QPS 肯定比 nginx 的低,看是否和现在的故障 QPS 一致;
    3. 如果一致,那很明显是 FPM 本身有瓶颈了。

    另外建议安装 atop,ganglia 等软件,实时查看服务器当前各项指标,加速找到问题原因。
    q937298063
        11
    q937298063  
    OP
       2019-05-27 17:01:32 +08:00
    @asilin 嗯 好的 多谢大佬。我先尝试一下。
    janxin
        12
    janxin  
       2019-05-27 17:05:22 +08:00
    看起来不是 nginx 的问题,具体的最好能拉一下 log

    几个有用 log 字段可以打印一下
    $upstream_connect_time
    $upstream_header_time
    $upstream_response_time
    tankerwng
        13
    tankerwng  
       2019-05-27 17:08:33 +08:00
    看看 access,请求没有超时的?全都是 200 ?
    q937298063
        14
    q937298063  
    OP
       2019-05-27 17:17:29 +08:00
    @janxin 嗯,好的,我修改一下,进行尝试
    q937298063
        15
    q937298063  
    OP
       2019-05-27 17:19:37 +08:00
    @asilin 我总觉得问题更大了。我 测试了一个静态的页面 里面也是啥也没有 就是一条 json 字符串。然后测试条件与上面一致,结果居然 有 4s 之多?
    danc
        16
    danc  
       2019-05-27 17:19:57 +08:00
    php 能达到 200 的并发就已经不错了吧
    q937298063
        17
    q937298063  
    OP
       2019-05-27 17:20:26 +08:00
    有很多,最多的时候有一半之多 502
    q937298063
        18
    q937298063  
    OP
       2019-05-27 17:21:12 +08:00
    @danc 真的假的 我翻过老的提问,他们都说 1 核 1G 就可以了。。。。
    ztxcccc
        19
    ztxcccc  
       2019-05-27 17:22:14 +08:00
    opcache 开了吗,如果开的话注意一下 opcache 的重新检测时间
    danc
        20
    danc  
       2019-05-27 17:22:36 +08:00
    我以前装个 wordpress, 不停的按 F5,就能宕机了.加个缓存还好点
    q937298063
        21
    q937298063  
    OP
       2019-05-27 17:32:19 +08:00
    @ztxcccc 这个我还真的不是很清楚 。。我这边也尝试下,多谢帮忙
    @danc 真的假的。。wordpress 不是挺有名的吗?
    ryd994
        22
    ryd994  
       2019-05-27 17:33:24 +08:00 via Android
    可能是虚拟网络处理能力不够了。特别是还有其他用户,不能把资源全给你。
    要排除很简单。走 loopback,通过 127.0.0.1 来测试就知道了。

    排除网络问题后,比较有可能是 PHP worker 太少。可以根据 Nginx 里的统计来判断。

    你说 CPU 占用 56%,这没有任何意义。可能某个核已经满了,但其他核还空着。要看分核的统计。比如 top 然后按数字 1。

    刚看到你说开启 keepalive 还是一样性能。那可能就不是网络问题。当然,排除网络问题之前先抓包确认 keepalive 有效。配置不对的话 keepalive 可能实际没启用。

    如果确认是网络问题可以找客服。或者使用网络增强实例,带 sriov 的那种,再试试看。
    q937298063
        23
    q937298063  
    OP
       2019-05-27 17:33:24 +08:00
    多谢大佬们帮忙,我先去尝试了,如果由哪位大佬知道,请动动小手啊。我就先不回复,去测试了。
    qianji201712
        24
    qianji201712  
       2019-05-27 17:36:42 +08:00
    带宽呢?也是很重要的信息
    ryd994
        25
    ryd994  
       2019-05-27 17:36:44 +08:00 via Android
    @q937298063 哪有 wp 裸奔的。肯定是要缓存的啊。前面套 Nginx 的作用之一就是缓存和分流静态。前端不好做缓存的话还要考虑在后端和数据库方向缓存。
    WordPress 流行是因为它简单易用。它性能好不好不是重点。一个博客,访问量能有多大?访问量大的又怎会没有人懂调优?
    ryd994
        26
    ryd994  
       2019-05-27 17:39:38 +08:00 via Android
    keepalive_timeout 0;

    你这就是没配置对,实际上根本没用 keepalive
    lzvezr
        27
    lzvezr  
       2019-05-27 17:41:24 +08:00 via iPhone
    worker_connections 设置一下,我之前遇到过并发 260 左右就无法再接入,后来发现是这个原因
    lzvezr
        28
    lzvezr  
       2019-05-27 17:42:07 +08:00 via iPhone
    @lzvezr 瞎了,没看到后面配置有设置 worker_connections
    rootww21
        29
    rootww21  
       2019-05-27 17:48:01 +08:00
    accept_mutex off;
    multi_accept on;
    这两个先去掉试试?
    q937298063
        30
    q937298063  
    OP
       2019-05-27 17:49:33 +08:00
    @qianji201712 带宽的话 目前服务器是按量走的 峰值 50M/s 我看了阿里云的记录,不是这个问题。
    q937298063
        31
    q937298063  
    OP
       2019-05-27 17:49:51 +08:00
    @rootww21 好的 我也尝试一下。
    pmispig
        32
    pmispig  
       2019-05-27 17:52:14 +08:00
    是在内网测的还是外网测,建议在内网开一个 4 核 4G 的临时实例再测一下
    q937298063
        33
    q937298063  
    OP
       2019-05-27 17:59:12 +08:00
    @ryd994 大佬 我开了 keepalive_timeout 设置为 60 之后 有的一定的效果了 但是不是很明显 大概 降了 1 秒左右现在 基本保持在了 7.5 秒左右 ,刚刚你说的那个 CPU 问题 我看了测试了一下,结果是 两个核都占了百分之 50 多 应该是没出现问题。多谢大佬
    az422
        34
    az422  
       2019-05-27 18:22:48 +08:00 via Android
    1. 确定压测是内网测试的? ab 客户端也在内网?
    2. 压测时 ab 所在机器负载如何, -c 不要 500 开始,先尝试 100, 200
    ladypxy
        35
    ladypxy  
       2019-05-27 18:38:46 +08:00 via iPhone
    worker_connections 51200;

    你这个设置太疯狂了,从哪抄的设置?
    你设置成 1024 就可以了……
    KasuganoSoras
        36
    KasuganoSoras  
       2019-05-27 18:43:10 +08:00
    PHP 5.6 效率不行,换 7.X 吧,又快,还支持新特性
    另外你可以试试我这个压测脚本,PHP 写的,需要 pthreads 支持
    https://github.com/kasuganosoras/ZeroCC
    命令:php zerocc.php localhost 80 300 /
    其中 localhost 是地址,80 是端口,300 是线程,/ 是 URI
    然后把 error_log 设置为 debug 等级,再进行压测,然后查看 error.log
    dragonsunmoon
        37
    dragonsunmoon  
       2019-05-27 22:57:44 +08:00
    ab -c 300 -n 500 地址
    这个地址是 ECS 分配的公网地址吗?
    如果是 ECS 分配的公网地址,通过这个公网地址访问,并发性能(并发数和 QPS )是上不去的。
    除非你购买阿里云的负载均衡服务(有独立的性能配置和带宽配置),通过阿里云的负载均衡服务转发请求到你的 ECS 上的 php 服务器上。
    q937298063
        38
    q937298063  
    OP
       2019-05-28 09:42:51 +08:00
    @dragonsunmoon 额 老哥 我这个地址是 ecs 分配的。。。 为什么并发会上不去啊。。
    q937298063
        39
    q937298063  
    OP
       2019-05-28 10:17:11 +08:00
    临时做法是,升级配置 翻了个倍 4 核 8G,感觉无解。楼上的办法基本都尝试过了,基本上没有效果,不过有些没有尝试 比如那个负载均衡之类的。
    目前,300 并发的响应,最迟 4s。
    我修改了 php-fpm.conf 的 pm 和 max_children 之后 发现变化效果明显。就是 max_children 变大后 响应时间明显变大,小到一定程度的时候响应明显减小。如果继续变小,则出现响应时间变大。
    q937298063
        40
    q937298063  
    OP
       2019-05-28 11:17:02 +08:00
    目前最后的测试结果,请求静态页面。使用命令 .\abs -k -c 300 -n 500 地址。

    参数说明
    $upstream_connect_time $upstream_header_time $upstream_response_time $request_time
    - - - 0.000

    日志记录
    125.109.131.170 - - [28/May/2019:11:08:26 +0800] "GET /500.html HTTP/1.0" 200 26 "-" "ApacheBench/2.3" "-"- - - 0.000
    125.109.131.170 - - [28/May/2019:11:08:26 +0800] "GET /500.html HTTP/1.0" 200 26 "-" "ApacheBench/2.3" "-"- - - 0.000
    125.109.131.170 - - [28/May/2019:11:08:26 +0800] "GET /500.html HTTP/1.0" 200 26 "-" "ApacheBench/2.3" "-"- - - 0.000
    125.109.131.170 - - [28/May/2019:11:08:26 +0800] "GET /500.html HTTP/1.0" 200 26 "-" "ApacheBench/2.3" "-"- - - 0.000
    125.109.131.170 - - [28/May/2019:11:08:26 +0800] "GET /500.html HTTP/1.0" 200 26 "-" "ApacheBench/2.3" "-"- - - 0.000


    测试返回
    Server Port: 443
    SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256

    Document Path: /500.html
    Document Length: 26 bytes

    Concurrency Level: 300
    Time taken for tests: 3.758 seconds
    Complete requests: 500
    Failed requests: 0
    Keep-Alive requests: 500
    Total transferred: 127500 bytes
    HTML transferred: 13000 bytes
    Requests per second: 133.07 [#/sec] (mean)
    Time per request: 2254.504 [ms] (mean)
    Time per request: 7.515 [ms] (mean, across all concurrent requests)
    Transfer rate: 33.14 [Kbytes/sec] received

    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 1286 1262.2 1119 3688
    Processing: 18 30 4.8 30 38
    Waiting: 18 30 4.8 30 38
    Total: 18 1315 1263.2 1153 3719

    Percentage of the requests served within a certain time (ms)
    50% 1153
    66% 1979
    75% 2440
    80% 2699
    90% 3213
    95% 3471
    98% 3624
    99% 3676
    100% 3719 (longest request)

    多的就不贴了 全是这个。我觉得 应该 像是

    @dragonsunmoon 说的那样应该是阿里云服务器的问题
    dragonsunmoon
        41
    dragonsunmoon  
       2019-05-28 22:25:55 +08:00
    @q937298063 我推测, 因为所有的公网过来的网络请求,都会经过阿里云的防火墙后,再转发到对应的 ECS 的内网 IP 上,而这个公网 IP 的连接数,转发速率是有限制的。
    腾讯云也有类似的问题, 所以腾讯云也一样有对应的负载均衡服务。
    阿里云和腾讯云提供的负载均衡服务实例,就是用在需要对外(对公网)提供大量并发,大量连接(长连接,或同时指支持的连接数非常高)的应用场景。反过来想,如果阿里云,腾讯云不对 ECS 上的网络进行限制,这个负载均衡服务存在的意义就不大了(不好卖钱了嘛)
    unknowncheater
        42
    unknowncheater  
       2019-05-30 11:53:43 +08:00
    ➕ buffer
    aru
        43
    aru  
       2019-05-31 18:02:04 +08:00
    公网带宽用光了,在内网通过内网 IP 测试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2881 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:30 · PVG 20:30 · LAX 04:30 · JFK 07:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.