Linux性能优化实战学习笔记:第二十六讲
一、案例环境描述
1、环境准备
2CPU,4GB内存
预先安装docker sysstat工具
2、温馨提示
案例中 Python 应用的核心逻辑比较简单,你可能一眼就能看出问题,但实际生产环境中的源码就复杂多了。所以,
我依旧建议,操作之前别看源码,避免先入为主,要把它当成一个黑盒来分析。这样 你可以更好把握住,怎么从系统的资源使用问题出发,分析出瓶颈
所在的应用,以及瓶颈在应用中大概的位置
3、应用环境
1、运行目标应用
docker run -v /tmp:/tmp --name=app -itd feisky/logapp
2、确认应用正常启动
ps -ef | grep /app.py
root 18940 18921 73 14:41 pts/0 00:00:02 python /app.py
二、故障现象
1、发现故障
# 按 1 切换到每个 CPU 的使用情况
$ top
top - 14:43:43 up 1 day, 1:39, 2 users, load average: 2.48, 1.09, 0.63
Tasks: 130 total, 2 running, 74 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.7 us, 6.0 sy, 0.0 ni, 0.7 id, 92.7 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.3 sy, 0.0 ni, 92.3 id, 7.3 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8169308 total, 747684 free, 741336 used, 6680288 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 7113124 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
18940 root 20 0 656108 355740 5236 R 6.3 4.4 0:12.56 python
1312 root 20 0 236532 24116 9648 S 0.3 0.3 9:29.80 python3
千万记得一定要用机械硬盘

2、性能现象

三、分析过程
1、iowait超过了90%分析
查看I/O使用情况
# -d 表示显示 I/O 性能指标,-x 表示显示扩展统计(即所有 I/O 指标)
$ iostat -x -d 1
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 64.00 0.00 32768.00 0.00 0.00 0.00 0.00 0.00 7270.44 1102.18 0.00 512.00 15.50 99.20
实际测试截图

观测结果分析
2、pidstat分析python进程
1、观察进程I/O使用情况
pidstat -d 1 15:08:35 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
15:08:36 0 18940 0.00 45816.00 0.00 96 python 15:08:36 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
15:08:37 0 354 0.00 0.00 0.00 350 jbd2/sda1-8
15:08:37 0 18940 0.00 46000.00 0.00 96 python
15:08:37 0 20065 0.00 0.00 0.00 1503 kworker/u4:2
2、实际测试截图
3、pidstat结果观测分析
实际测试说明
1、io使用没有达到90%,而实际测试是14.9(最高)
2、每秒的写请求是64,而实际测试是85
3、写大小32MB,而实际测试是107MB
4、请求队列是1100而实际测试是23.93
3、strace分析python进程调用
1、strace查看指定PID调用情况
strace -p 18940
strace: Process 18940 attached
...
mmap(NULL, 314576896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0f7aee9000
mmap(NULL, 314576896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0f682e8000
write(3, "2018-12-05 15:23:01,709 - __main"..., 314572844
) = 314572844
munmap(0x7f0f682e8000, 314576896) = 0
write(3, "\n", 1) = 1
munmap(0x7f0f7aee9000, 314576896) = 0
close(3) = 0
stat("/tmp/logtest.txt.1", {st_mode=S_IFREG|0644, st_size=943718535, ...}) = 0
2、实际测试截图:机械硬盘 centos

3、strace结果观测分析

4、lsof查看python进程打开了那些文件
1、查看进程打开了那些文件
lsof -p 18940
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python 18940 root cwd DIR 0,50 4096 1549389 /
python 18940 root rtd DIR 0,50 4096 1549389 /
…
python 18940 root 2u CHR 136,0 0t0 3 /dev/pts/0
python 18940 root 3w REG 8,1 117944320 303 /tmp/logtest.txt
2、实际测试截图

3、lsof输出观测分析

3、查看源代码
# 拷贝案例应用源代码到当前目录
$ docker cp app:/app.py . # 查看案例应用的源代码
$ cat app.py logger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)
rHandler = RotatingFileHandler("/tmp/logtest.txt", maxBytes=1024 * 1024 * 1024, backupCount=1)
rHandler.setLevel(logging.INFO) def write_log(size):
'''Write logs to file'''
message = get_message(size)
while True:
logger.info(message)
time.sleep(0.1) if __name__ == '__main__':
msg_size = 300 * 1024 * 1024
write_log(msg_size)
继续查看源码
def set_logging_info(signal_num, frame):
'''Set loging level to INFO when receives SIGUSR1'''
logger.setLevel(logging.INFO) def set_logging_warning(signal_num, frame):
'''Set loging level to WARNING when receives SIGUSR2'''
logger.setLevel(logging.WARNING) signal.signal(signal.SIGUSR1, set_logging_info)
signal.signal(signal.SIGUSR2, set_logging_warning)
分析这个源码,我们发现,它的日志路径是/tmp/logtest.txt、默认记录 INFO 级别以上的所有日志,而且每次写日志的大小是 300MB。这跟我们上面的分析结果是一致的
四、解决方案
1、运行kill命令给进程发SIGUSR2 信号
kill -SIGUSR2 18940
2、再执行top和iostat观察
top
top
...
%Cpu(s): 0.3 us, 0.2 sy, 0.0 ni, 99.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
iowat
iostat -d -x 1
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
到这里,我们不仅定位了狂打日志的应用程序,并通过调用高日志级别的方法,完美解决了I/O的性能瓶颈
五、小结
日志,是了解应用程序内部运行情况、最常用、也最高效的工具、无论是操作系统、还是应用程序、都会记录大量的运行日志,以便时候查看历史记录,
这些日志一般按照不同的级别来开启,比如,开发环境通常打开调式级别的日志,而线上环境则只记录警告和错误日志
在排查应用程序问题时,我们可以能需要,在线上环境临时开启应用程序的调试日志,有时候,事后一不小心忘了调回去,没把线上的日志调高到警告级别,
可能会导致cpu使用率、磁盘I/O等一系列的性能问题,严重时,甚至会影响同一台服务器上运行的其他应用程序
今后,在碰到这种“狂打日志”的场景时,你可以用iostat、strace、losf等工具来定位狂打日志的进程,找出相应的日志文件,再通过应用程序接口
调整日志界别来解决问题
Linux性能优化实战学习笔记:第二十六讲的更多相关文章
- Linux性能优化实战学习笔记:第六讲
一.环境准备 1.安装软件包 终端1 机器配置:2 CPU,8GB 内存 预先安装 docker.sysstat.perf等工具 [root@luoahong ~]# docker -v Docker ...
- Linux性能优化实战学习笔记:第六讲1
一.环境准备 1.安装软件包 终端1 机器配置:2 CPU,8GB 内存 预先安装 docker.sysstat.perf等工具 [root@luoahong ~]# docker -v Docker ...
- Linux性能优化实战学习笔记:第十七讲
一.缓存命中率 1.引子 1.我们想利用缓存来提升程序的运行效率,应该怎么评估这个效果呢? 用衡量缓存好坏的指标 2.有没有哪个指标可以衡量缓存使用的好坏呢? 缓存命中率 3.什么是缓存命中率? 所谓 ...
- Linux性能优化实战学习笔记:第七讲
一.进程的状态 1.命令查看 top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 28961 root 20 0 43816 3148 ...
- Linux性能优化实战学习笔记:第四讲
一.怎么查看系统上下文切换情况 通过前面学习我么你知道,过多的上下文切换,会把CPU时间消耗在寄存器.内核栈以及虚拟内存等数据的保存和回复上,缩短进程真正运行的时间,成了系统性能大幅下降的一个元凶 既 ...
- Linux性能优化实战学习笔记:第八讲
一.环境准备 1.在第6节的基础上安装dstat wget http://mirror.centos.org/centos/7/os/x86_64/Packages/dstat-0.7.2-12.el ...
- Linux性能优化实战学习笔记:第十一讲
一.性能指标 1.性能指标思维导图 2.CPU使用率 3.CPU平均负载 4.CPU缓存的命中率 CPU 在访问内存的时候,免不了要等待内存的响应.为了协调这两者巨大的性能差距,CPU 缓存(通常是多 ...
- Linux性能优化实战学习笔记:第四十五讲
一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...
- Linux性能优化实战学习笔记:第三十六讲
一.上节总结回顾 上一节,我们回顾了经典的 C10K 和 C1000K 问题.简单回顾一下,C10K 是指如何单机同时处理 1 万个请求(并发连接 1 万)的问题,而 C1000K 则是单机支持处理 ...
- Linux性能优化实战学习笔记:第四十三讲
一.上节回顾 上一节,我们了解了 NAT(网络地址转换)的原理,学会了如何排查 NAT 带来的性能问题,最后还总结了 NAT 性能优化的基本思路.我先带你简单回顾一下. NAT 基于 Linux 内核 ...
随机推荐
- windowsServer ------ 安装IIS
1.找到服务器管理器,点击添加角色,一步步执行 2.添加IIS 相关组件 勾选web服务器 下一步 将web服务iis 相关组件全部勾选,ftp 可不选 选择好后安装 等一会 关闭 可以查看到所安装角 ...
- learning rate warmup实现
def noam_scheme(global_step, num_warmup_steps, num_train_steps, init_lr, warmup=True): ""& ...
- 使用Charles进行HTTPS抓包及常见问题
在渗透过程中,需要对每一个参数,每一个接口,每一个业务逻辑构建测试用例,为此,抓包分析是必不可少的一个过程.在PC端,Burpsuite成为了渗透必备的神器,然而,使用Burpsuite有时候抓取不到 ...
- cuda,cudnn
20191008 服务器上的cuda总是被人搞坏掉,好烦.记录下: 卸载干净cuda sudo rm -rf /usr/local/cuda sudo apt-get remove cuda sudo ...
- identityServer3+ADFS实现域用户登录授权
准备: ADFS安装配置 https://www.cnblogs.com/luoyedemeng/articles/9837685.html 添加一个Providers private void Co ...
- LR实现处理PUT方法的案例
- Qt for Android使用grpc探索
利用Qt在Android上使用grpc需要*.a的静态库,Windows上编译的lib库以及linux编译出来的.a,经过尝试,均无法链接成功.本文尝试使用NDK来编译Android版本的grpc静态 ...
- LNMP环境下搭建SVN服务
最近自己买了个服务器,试着在上面搭建了LNMP环境,因为以前在本地用MAMP Pro搭建过LAMP环境,所以基本上还算是轻车熟路,第一次搭建LNMP,使用的是一键安装,过程是顺利的,后来在使用过程中遇 ...
- Linux(Centos7)搭建LAMP(Apache+PHP+Mysql环境)
目录 Linux搭建LAMP(Apache+PHP+Mysql环境)Centos7 一. 检查系统环境 1.确认centos版本 2.检查是否安装过apache 3.检查是否安装过Mysql 4.清理 ...
- 更换Ubuntu软件源
对于Ubuntu系统, 不同的版本的源都不一样,每一个版本都有自己专属的源. 而对于 Ubuntu 的同一个发行版本,它的源又分布在全球范围内的服务器上.Ubuntu 默认使用的官方源的服务器在欧洲, ...



