php运行cpu利用率低,案例:某个应用的 CPU 使用率居然达到 100%,我该怎么办?...

环境准备

两台虚拟机(Ubuntu 18.04)

机器配置:2 CPU,8GB 内存

预先安装 docker、sysstat、perf、ab 等工具,如 apt install docker.io sysstat linux-tools-common apache2-utils

操作和分析

其中一台用作 Web 服务器,来模拟性能问题;另一台用作 Web 服务器的客户端,来给 Web 服务增加压力请求。

打开两个终端,分别 SSH 登录到两台机器上,并安装上面提到的工具。

默认以 root 用户运行所有命令,先运行 sudo su root 命令切换到 root 用户。

由于 Nginx 和 PHP 的配置比较麻烦, 课程提供了两个Docker 镜像,这样只需要运行两个容器,就可以得到模拟环境。

运行docker容器应用

首先,在第一个终端执行下面的命令来运行 Nginx 和 PHP 应用:

$ docker run --name nginx -p 10000:80 -itd feisky/nginx

$ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm

下载过程可能比较缓慢…下载完成后,执行 docker ps -a ,如图:

ebd3909bccc9b97d9a7aca095ab82f4f.png

第二个终端使用 curl 访问 http://[VM1 的 IP]:10000,确认 Nginx 已正常启动。

# 192.168.139.139是第一台虚拟机的IP地址

$ curl http://192.168.139.139:10000/

如图:

f57ab380ad7898da66cdf9bee06753e6.png

压力测试一

在第二个终端运行下面的 ab 命令:

# 并发10个请求测试Nginx性能,总共测试100个请求

$ ab -c 10 -n 100 http://192.168.139.139:10000/

如图:

9564583a7a1dddcda1a92c3640a85b66.png

从 ab 的输出结果我们可以看到,Nginx 能承受的每秒平均请求数只有 11.47。这个数据实际是很差的,如果暂时感觉不到什么,那尝试用 top 和 pidstat 再做观察。

压力测试二

继续在第二个终端,运行 ab 命令:

# 这次将测试的请求总数增加到10000

$ ab -c 10 -n 10000 http://192.168.139.139:10000/

回到第一个终端运行 top 命令,并按下数字 1 ,切换到每个 CPU 的使用率:

db4db88d6f9a502e3c5efb66353bb2d1.png

这里可以看到,系统中有几个 php-fpm 进程的 CPU 使用率加起来接近 100%;而 CPU 的用户使用率(us)也已经超过了 99%,接近饱和。这里猜测是用户空间的 php-fpm 进程,导致 CPU 使用率骤升。

perf 分析 php-fpm 进程

那怎么知道是 php-fpm 的哪个函数导致了 CPU 使用率升高呢?我们来用 perf 分析一下。

在第一个终端运行下面的 perf 命令(如果提示命令not found,按提示安装即可):

# -g开启调用关系分析,-p指定php-fpm的进程号2250

$ perf top -g -p 2250

如图:

95a6c6382acb343ab50ac22469429971.png

通过方向键移动到 php-fpm 进程,通过 enter 键展开 + 号位置的内容,如图:

b2e03720d69aaad4c0bb20c66578b284.png

可以看到,调用关系最终到了 sqrt 和 add_function。

grep 查找具体函数

尝试将PHP源码拷贝出来,然后查看是不是调用了这两个函数,

# 从容器phpfpm中将PHP源码拷贝出来

$ docker cp phpfpm:/app .

# 使用grep查找函数调用

$ grep sqrt -r app/ #找到了sqrt调用

$ grep add_function -r app/ #没找到add_function调用,这其实是PHP内置函数

如图:

f2fd48111a9dfa1fd6cbb68240299cff.png

到这里可知,只有 sqrt 函数在 app/index.php 被调用。最后我们来看下这个文件源代码,

6c167730fd07ea62664b70692f776228.png

其实,这里的本意,//test only 下的代码是不应该存在的,因为它造成多余地消耗CPU。代码虽然简单,但我们还是尝试把测试代码删除,再看看执行效果吧。

优化应用代码

课程提供了一个优化后的镜像,可以如下操作:

# 停止原来的应用

$ docker rm -f nginx phpfpm

# 运行优化后的应用

$ docker run --name nginx -p 10000:80 -itd feisky/nginx:cpu-fix

$ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:cpu-fix

不过,我想直接在现有容器上修改,修改已经拷贝出来的 index.php

7e87a26e4d6ef5e3fe8c01baf23ebb2f.png

然后覆盖到php-fpm容器里面,并验证是否更新了代码,

037e88063b24275c5ed94a4888dbac05.png

压力测试三

确保终端一正常运行 Nginx 和 PHP 应用,切换到终端二,首先 Ctrl+C 停止之前的 ab 命令后,再运行下面的命令:

ab -c 10 -n 10000 http://192.168.139.139:10000/

如图:

1bf35659733ae979f2c179ccf4ceed37.png

可以看到,现在每秒的平均请求数,已经从原来的 11 变成了 1222。

结语

本案例代码设计较为简单,工作中可能遇到更加复杂的问题,这里只是分享下,一种查找发现问题的方法。

同时,我会把更多实践案例归纳在 Linux 性能优化笔记 文章底部,欢迎阅读。

e6ce4419803539ae9195228b2d530747.png

本作品采用《CC 协议》,转载必须注明作者和本文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值