文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PHP-FPM进程数不够怎么办

2023-06-22 00:37

关注

这篇文章给大家分享的是有关PHP-FPM进程数不够怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

感觉PHP-FPM进程数不够?

作为一个 phper,用的最多的架构就是 LNMP。每次一到流量来了,我们的服务就从原来的 几百毫秒到几秒的时间。这个时候我们各种猜测,mysql 有慢 sql,redis 有大 key,php-fpm 进程数不够等等情况。其中可以通过业务的一些日志来排查如上情况。我们这次主要证明的却是 php-fpm 进程数不够情况的实践。

重现现场

将我本地的的 PHP-FPM 进程数调整为 2

#vim /etc/php-fpm.d/www.confpm = staticpm.max_children = 2

使用 ab 来压测接口

$ ab -c 40  -n 3000 http://127.0.0.1/group/check_groupsServer Software:        nginx/1.16.0Server Hostname:        miner_platform.cnServer Port:            80Document Path:          /group/check_groupsDocument Length:        44 bytesConcurrency Level:      40Time taken for tests:   29.384 secondsComplete requests:      3000Failed requests:        0Write errors:           0Total transferred:      699000 bytesHTML transferred:       132000 bytesRequests per second:    102.10 [#/sec] (mean)Time per request:       391.788 [ms] (mean)Time per request:       9.795 [ms] (mean, across all concurrent requests)Transfer rate:          23.23 [Kbytes/sec] receivedConnection Times (ms)              min  mean[+/-sd] median   maxConnect:        0    0   0.2      0       3Processing:   306  344  80.6    318    3558Waiting:      306  343  80.5    318    3555Total:        307  344  80.6    318    3558Percentage of the requests served within a certain time (ms)  50%    318  66%    322  75%    333  80%    369  90%    428  95%    461  98%    508  99%    553 100%   3558 (longest request)

尝试解决问题

1. PHP-FPM STATUS

我们发现接口 318ms 到 3.558s 的都有,那我们如何知道 php-fpm 进程少不够导致这个问题呢?换一种说话有什么办法能让我们知道 php-fpm 内部是处理不过来吗? 这个时候我们就需要打开 php-fpm 内置 status 了。

详细步骤参考:https://www.yisu.com/php-weizijiaocheng-485633.html

$ curl http://127.0.0.1/status.phppool:                 wwwprocess manager:      staticstart time:           29/Nov/2021:18:27:38 +0800start since:          6493accepted conn:        3136listen queue:         38max listen queue:     39listen queue len:     128idle processes:       0active processes:     2total processes:      2max active processes: 2max children reached: 0slow requests:        0

具体详细的字段可以参见上面的链接,有详细说明,我们主要说下几个参数

netstat 查看链接状态

我们得到的结论是:当 php-fpm 进程处理不过来的时候,请求就会放在 accept 队列,知道了这个情况以后,我们甚至不需要通过 status。

第一行表示的监听 socket, Recv-Q 表示 accept queue 长度。

$netstat -antp | grep php-fpmtcp       38      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      97/php-fpm: master  tcp        8      0 127.0.0.1:9000          127.0.0.1:55540         ESTABLISHED 964/php-fpm: pool w tcp        8      0 127.0.0.1:9000          127.0.0.1:55536         ESTABLISHED 965/php-fpm: pool w

综上我们知道了,当 PHP-FPM 进程数不够的时候,nginx 客户端请求的连接的 accept 队列 长度就会变大。这样就完了吗?不,我们还需要去分析为什么能得到这个现象。

原理分析

简述 PHP-FPM 工作过程

首先我们需要简单里说一说 php-fpm 的工作过程。我们就简单模型一下它的伪代码(这里只为了表述整个 socket 的过程)

// 1. 创建 socket$socket = socket_create(AF_INET, SOCK_STREAM, 0);// 2. 绑定socketsocket_bind($socket, "0.0.0.0", 9000);// 3. 监听 socketsocket_listen($socket, 5);for($i=0;$i<2;$i++) {    $pid = pcntl_fork()    // 4. 创建2个进程    if ($pid == 0) {        // 5. 子进程接受socket        while($fd = socket_accept($socket)) {            echo "客户端${fd}连接" . PHP_EOL;            $tmp = socket_read($fd, 1024);            echo "client data:" . $tmp . PHP_EOL;            $data = "HTTP/1.1 200 ok\r\nContent-Length:2\r\n\r\nhi";            socket_write($fd, $data, strlen($data));        }            exit;    }}// 5. 监听子进程退出// 其他 TODO

master 进程创建了监听 socket,但是不处理业务正在

work 进程接受同步堵塞接受请求(堵塞在 accept),然后处理业务。

抓取 nginx->php-fpm socket

我们知道了 php-fpm 大概工作的过程,这个时候我们就需要通过一次请求大概知道 nginx 与 php-fpm 交互的过程。

$curl http://miner_platform.cn/group/check_groups{"code":10006,"message":"sign\u65e0\u6548."}

1.nginx 系统调用

需要关注的点都在这个里面注释了。抓取的是 nginx work 进程

$ strace -f -s 64400 -p 958 strace: Process 958 attached epoll_wait(8, [{EPOLLIN, {u32=1226150064, u64=94773974503600}}], 512, -1) = 1 accept4(6, {sa_family=AF_INET, sin_port=htons(46616), sin_addr=inet_addr("127.0.0.1")}, [112->16], SOCK_NONBLOCK) = 3 epoll_ctl(8, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=1226159737, u64=94773974513273}}) = 0 epoll_wait(8, [{EPOLLIN, {u32=1226159737, u64=94773974513273}}], 512, 60000) = 1 recvfrom(3, "GET /group/check_groups HTTP/1.1\r\nUser-Agent: curl/7.29.0\r\nHost: miner_platform.cn\r\nAccept: **\0\0\0\0\0\0\0\1\4\0\1\0\0\0\0\1\5\0\1\0\0\0\0", iov_len=592}], 1) = 592 epoll_wait(8, [{EPOLLIN|EPOLLOUT, {u32=1226163953, u64=94773974517489}}], 512, 60000) = 1 // 4. 接受 PHP-FPM响应结果    recvfrom(11, "\1\6\0\1\0\257\1\0X-Powered-By: PHP/7.2.16\r\nCache-Control: no-cache, private\r\nDate: Wed, 01 Dec 2021 12:24:52 GMT\r\nContent-Type: application/json\r\n\r\n{\"code\":10006,\"message\":\"sign\\u65e0\\u6548.\"}\0\1\3\0\1\0\10\0\0\0\0\0\0\0\"}\0", 4096, 0, NULL, NULL) = 200 epoll_wait(8, [{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=1226163953, u64=94773974517489}}], 512, 60000) = 1 readv(11, [{iov_base="", iov_len=3896}], 1) = 0 // 5. 关闭这次socket连接     close(11)                               = 0 // 6. 响应给浏览器     writev(3, [{iov_base="HTTP/1.1 200 OK\r\nServer: nginx/1.16.0\r\nContent-Type: application/json\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nX-Powered-By: PHP/7.2.16\r\nCache-Control: no-cache, private\r\nDate: Wed, 01 Dec 2021 12:24:52 GMT\r\n\r\n", iov_len=222}, {iov_base="2c\r\n", iov_len=4}, {iov_base="{\"code\":10006,\"message\":\"sign\\u65e0\\u6548.\"}", iov_len=44}, {iov_base="\r\n", iov_len=2}, {iov_base="0\r\n\r\n", iov_len=5}], 5) = 277 write(5, "127.0.0.1 - - [01/Dec/2021:20:24:52 +0800] \"GET /group/check_groups HTTP/1.1\" 200 55 \"-\" \"curl/7.29.0\" \"-\" 1.029 127.0.0.1:9000 200 1.030\n", 138) = 138 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0 epoll_wait(8, [{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=1226159737, u64=94773974513273}}], 512, 65000) = 1 recvfrom(3, "", 1024, 0, NULL, NULL)    = 0 close(3)                                = 0 epoll_wait(8,

2.php-fpm 系统调用

抓取了 php-fpm work 进程

// 1. accept 接收到了 nginx(127.0.0.1:45512 ) 客户端发送的数据965   accept(9, {sa_family=AF_INET, sin_port=htons(45512), sin_addr=inet_addr("127.0.0.1")}, [112->16]) = 4中间省略了许多// 2. 响应给客户端965   write(4, "\1\6\0\1\0\257\1\0X-Powered-By: PHP/7.2.16\r\nCache-Control: no-cache, private\r\nDate: Wed, 01 Dec 2021 12:37:18 GMT\r\nContent-Type: application/json\r\n\r\n{\"code\":10006,\"message\":\"sign\\u65e0\\u6548.\"}\0\1\3\0\1\0\10\0\0\0\0\0\0\0p\0\0", 200) = 200// 3. 不给给这个socket 写数据了965   shutdown(4, SHUT_WR)              = 0// 4. 接受nginx(127.0.0.1:45512 )客户端数据 965   recvfrom(4, "\1\5\0\1\0\0\0\0", 8, 0, NULL, NULL) = 8// 5. 接受nginx(127.0.0.1:45512 )客户端数据 965   recvfrom(4, "", 8, 0, NULL, NULL) = 0// 6. 关闭这个连接965   close(4)                          = 0965   lstat("/data/miner_platform/src/vendor/composer/../../app/Http/Middleware/BusinessHeaderCheck.php", {st_mode=S_IFREG|0777, st_size=989, ...}) = 0965   stat("/data/miner_platform/src/app/Http/Middleware/BusinessHeaderCheck.php", {st_mode=S_IFREG|0777, st_size=989, ...}) = 0965   chdir("/")                        = 0965   times({tms_utime=3583, tms_stime=1977, tms_cutime=0, tms_cstime=0}) = 4315309933965   setitimer(ITIMER_PROF, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=0, tv_usec=0}}, NULL) = 0965   fcntl(3, F_SETLK, {l_type=F_UNLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = 0965   setitimer(ITIMER_PROF, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=0, tv_usec=0}}, NULL) = 0965   accept(9,

TCP 三次握手

上面我们已经清楚了一次请求,请求并发高的时候流程也是如此,这个时候我们就引出了下面这个图与我们上面描述的过程是一样的,只是细化了三次握手的过程。这个时候我们引出了 sync queue 和 accept queue。

PHP-FPM进程数不够怎么办

感谢各位的阅读!关于“PHP-FPM进程数不够怎么办”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯