Linux性能优化实战学习笔记:第六讲1
一、环境准备
1、安装软件包
终端1
机器配置:2 CPU,8GB 内存 预先安装 docker、sysstat、perf等工具
[root@luoahong ~]# docker -v
Docker version 18.09.1, build 4c52b90
[root@luoahong ~]# rpm -qa|grep sysstat
sysstat-12.1.2-1.x86_64
终端2
机器配置:1 CPU,2GB 内存 预先安装ab 等工具
[root@nfs ~]#yum -y install httpd-tools
[root@nfs ~]# ab -V
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
2、实战拓谱图
二、操作和分析
1、发现问题
首先在第一个终端执行的命令来运行Nnginx和PHP应用
$ docker run --name nginx -p 10000:80 -itd feisky/nginx
$ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm
第二个终端测试确认Nnginx已经正常启动
[root@nfs ~]# curl http://192.168.118.97:10000
It works!
第二个终端测试Nnginx服务的性能
# 并发 10 个请求测试 Nginx 性能,总共测试 100 个请求
[root@nfs ~]# ab -c 10 -n 100 http://192.168.118.97:10000/
......
Requests per second: 24.07 [#/sec] (mean)
......
第二个终端测试Nnginx服务的性能加大压力测试
# 并发 10000个请求测试 Nginx 性能,总共测试 100 个请求
[root@nfs ~]# ab -c 10 -n 10000 http://192.168.118.97:10000/
......
Requests per second: 24.07 [#/sec] (mean)
......
top查看终端一
这里看一看到,系统中有几个php-fpm进程的CPU使用率加起来接近200%;而每个CPU的用户使用率已经超过了
98%,接近跑和,这样就可以确认,正是用户空间的PHP-fpm进程导致CPU使用率骤升
终端一运行perf 命令
按方向键切换到PHP-FPM,再按下回车键展开php-fpm的调用关系,你会发现,调用关系最终到了sqrt 和 add_function。看来,我们需要从这两个函数入手了
2、解决问题
我们拷贝出 Nginx 应用的源码,看看是不是调用了这两个函:
# 从容器 phpfpm 中将 PHP 源码拷贝出来
$ docker cp phpfpm:/app . # 使用 grep 查找函数调用
$ grep sqrt -r app/ # 找到了 sqrt 调用
app/index.php: $x += sqrt($x);
$ grep add_function -r app/ # 没找到 add_function 调用,这其实是 PHP 内置函数
原来只有 sqrt 函数在 app/index.php 文件中调用了。那最后一步,我们就该看看这个文件的源码了:
cat app/index.php
<?php
// test only.
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
$x += sqrt($x);
} echo "It works!"
测试代码没删除就直接发布应用了,为了方便你验证优化后的效果。我们修复好的应用打包成了一个
Docker 镜像,你可以在第一个终端中执行下面的命令来运行它
# 停止原来的应用
$ 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
终端二验证修复的效果
[root@nfs ~]# ab -c 10 -n 10000 http://192.168.118.97:10000/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.118.97 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests Server Software: nginx/1.15.6
Server Hostname: 192.168.118.97
Server Port: 10000 Document Path: /
Document Length: 153 bytes Concurrency Level: 10
Time taken for tests: 10.776 seconds
Complete requests: 10000
Failed requests: 992
(Connect: 0, Receive: 0, Length: 992, Exceptions: 0)
Write errors: 0
Non-2xx responses: 9008
Total transferred: 2900048 bytes
HTML transferred: 1387152 bytes
Requests per second: 928.00 [#/sec] (mean)
Time per request: 10.776 [ms] (mean)
Time per request: 1.078 [ms] (mean, across all concurrent requests)
Transfer rate: 262.82 [Kbytes/sec] received
从这里你可以发现,现在美秒的平均请求数,已经从原来的24变成了928
三、执行perf top -g -p (php-fpm进程号),发现不了sqrt函数
1、故障现象
我的系统是centos7,上次实战用 perf top -g -p pid没有看到函数名称,只能看到一堆十六进制的东西,然后老师给了解决方法,我转述下:
分析:当没有看到函数名称,只看到了十六进制符号,下面有Failed to open /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4, continuing without symbols 这说明perf无法找到待分析进程所依赖的库。这里只显示了一个,但其实依赖的库还有很多。这个问题其实是在分析Docker容器应用时经常会碰到的一个问题,因为容器应用所依赖的库都在镜像里面。
2、解决办法
老师给了两个解决思路:
(1)在容器外面构建相同路径的依赖库。这种方法不推荐,一是因为找出这些依赖比较麻烦,更重要的是构建这些路径会污染虚拟机的环境。
(2)在容器外面把分析纪录保存下来,到容器里面再去查看结果,这样库和符号的路径就都是对的了。
操作:
(1)在Centos系统上运行 perf record -g -p <pid>,执行一会儿(比如15秒)按ctrl+c停止
(2)把生成的 perf.data(这个文件生成在执行命令的当前目录下,当然也可以通过查找它的路径 find | grep perf.data或 find / -name perf.data)文件拷贝到容器里面分析:
docker cp perf.data phpfpm:/tmp
docker exec -i -t phpfpm bash
$ cd /tmp/
$ apt-get update && apt-get install -y linux-perf linux-tools procps
$ perf_4.9 report
注意:最后运行的工具名字是容器内部安装的版本 perf_4.9,而不是 perf 命令,这是因为 perf 会去跟内核的版本进行匹配,但镜像里面安装的perf版本有可能跟虚拟机的内核版本不一致。
注意:上面的问题只是在centos系统中有问题,ubuntu上没有这个问题
Linux性能优化实战学习笔记:第六讲1的更多相关文章
- Linux性能优化实战学习笔记:第四十一讲
一.上节回顾 上一节,我们探究了网络延迟增大问题的分析方法,并通过一个案例,掌握了如何用hping3.tcpdump.Wireshark.strace 等工具,来排查和定位问题的根源. 简单回顾一下, ...
- Linux性能优化实战学习笔记:第九讲
一.中断的魅力 1.中断在生活的魅力 比如你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了.所以你指能苦苦等着 ...
- Linux性能优化实战学习笔记:第三十六讲
一.上节总结回顾 上一节,我们回顾了经典的 C10K 和 C1000K 问题.简单回顾一下,C10K 是指如何单机同时处理 1 万个请求(并发连接 1 万)的问题,而 C1000K 则是单机支持处理 ...
- Linux性能优化实战学习笔记:第五十六讲
一.上节回顾 上一节,我带你一起梳理了,性能问题分析的一般步骤.先带你简单回顾一下. 我们可以从系统资源瓶颈和应用程序瓶颈,这两个角度来分析性能问题的根源. 从系统资源瓶颈的角度来说,USE 法是最为 ...
- Linux性能优化实战学习笔记:第四十三讲
一.上节回顾 上一节,我们了解了 NAT(网络地址转换)的原理,学会了如何排查 NAT 带来的性能问题,最后还总结了 NAT 性能优化的基本思路.我先带你简单回顾一下. NAT 基于 Linux 内核 ...
- Linux性能优化实战学习笔记:第四十五讲
一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...
- Linux性能优化实战学习笔记:第五十二讲
一.上节回顾 上一节,我们一起学习了怎么使用动态追踪来观察应用程序和内核的行为.先简单来回顾一下.所谓动态追踪,就是在系统或者应用程序还在正常运行的时候,通过内核中提供的探针,来动态追踪它们的行为,从 ...
- Linux性能优化实战学习笔记:第五十五讲
一.上节回顾 上一节,我们一起学习了,应用程序监控的基本思路,先简单回顾一下.应用程序的监控,可以分为指标监控和日志监控两大块. 指标监控,主要是对一定时间段内的性能指标进行测量,然后再通过时间序列的 ...
- Linux性能优化实战学习笔记:第五十八讲
一.上节回顾 专栏更新至今,咱们专栏最后一部分——综合案例模块也要告一段落了.很高兴看到你没有掉队,仍然在积极学习思考.实践操作,并热情地分享你在实际环境中,遇到过的各种性能问题的分析思路以及优化方法 ...
- Linux性能优化实战学习笔记:第三十一讲
一.上节回顾 上一节,我们一起回顾了常见的文件系统和磁盘 I/O 性能指标,梳理了核心的 I/O 性能观测工具,最后还总结了快速分析 I/O 性能问题的思路. 虽然 I/O 的性能指标很多,相应的性能 ...
随机推荐
- C#异步的世界【下】(转)
接上篇:<C#异步的世界[上]> 上篇主要分析了async\await之前的一些异步模式,今天说异步的主要是指C#5的async\await异步.在此为了方便的表述,我们称async\aw ...
- Redis(六)管道(Pipelining)
管道技术并不是Redis特有的,管道技术在计算机科学中有很多地方的应用. 来自wiki的解释: In computing, a pipeline, also known as a data pipel ...
- HBase统计表行数(RowCount)的四种方法
背景:对于其他数据存储系统来说,统计表的行数是再基本不过的操作了,一般实现都非常简单:但对于HBase这种key-value存储结构的列式数据库,统计 RowCount 的方法却有好几种不同的花样,并 ...
- WebAPI HelpPage帮助页
WebAPI HelpPage是个插件,根据代码的注释生成API说明页,一目了然. 下面开始安装和配置 1.添加引用 先选择管理NuGet程序包,搜索 Microsoft.AspNet.WebApi. ...
- mysql 实现row_number功能
需求: 解答:由于mysql 中没有类似oracle中的 row_number功能,要实现row_number 可以使用如下功能: Select pkid,(@row_number:=@row_num ...
- Layui 时间转换时间戳
我比较喜欢用Layui,当然也遇到一些坑!例如:绑定时间的时候是那种 是这种13位数据的日期,如果不经过转换是不能正常显示的,当然这是我遇到的问题不知道你们有没有遇到,后来我也是经过了解才知道怎么回事 ...
- 获取apache ignite缓存中的数据行数少于实际行数
我将ignite项目打包放到linux下,在linux下获取window中存放在oracle数据库中的数据,linux服务器作为ignite的服务端节点,我在本地启动tomact,作为ignite客户 ...
- vue Router——基础篇
vue--Router简介 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用. vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路 ...
- thinkphp5连接sql server
我用的环境是phpstudy,php版本是5.6,thinkphp连接sql server 方法如下: 1.修改database.php文件里的数据库信息 2.进入php扩展目录.我的是“E:\php ...
- java随机数获取
/**Number One: * 随机数获取公式:(数据类型)(最小值+Math.random()*(最大值-最小值+1)) * 随机数获取公式:(类型)最小值+Math.random()*最大值 * ...