写点什么

【优化技术专题】「系统性能调优实战」终极关注应用系统性能调优及原理剖析(上册)

作者:浩宇天尚
  • 2022 年 1 月 30 日
  • 本文字数:5168 字

    阅读完需:约 17 分钟

背景介绍

  1. 本人是做呼叫中心服务的,但是最近需要将系统性能和吞吐提升更高的能力和层次,所以便进行先关系统性质的学习和优化相关的技术做了一定的研究。

调优背景

因为当出现吞吐远远不能够满足我们客户或者我们需要的呼叫了指标的时候因为出现了这么一次情况,虽然没有给用户没有给公司带来什么损失,但是该现象从侧面已经反应出了系统某些方面的问题,或许系统参数需要优化一番,或许系统设计交互需要优化一番,或许等等等的可能,才有了后续系统调优的历程。

计划优化的要点方向

  1. 流程相关分析优化:看看哪些流程可以同步转异步处理,可以梳理一下哪些请求可以合并起来,Server 服务端的哪些业务场景需要补偿机制等。

  2. 数据库相关分析优化:哪些 Sql 耗时较长,哪些方法可以去除事务且去除事务后的带来的问题场景分析,数据库连接池参数是否合理,数据库本身相关参数的阈值情况的一些综合考虑;

  3. 内存使用情况分析优化:新老年代内存使用率及回收情况,CPU 使用率,磁盘使用率,swap 区使用情况, 线程 dump,堆 dump。

  4. JVM 参数分析调优:YGC 的平均耗时,YGC 的平均间隔,FGC 的平均耗时,FGC 的平均间隔等等,根据具体情况反映具体问题;

  5. TCP/Tomcat 参数分析调优:这个得根据实际压测情况来相应评估是否需要调整;

Linux 命令相关查看指标

CPU 指标

每n秒采集一次,一共采集m次vmstat n m
复制代码


  • r 表示运行队列,r 值一般负载超过了 3 就比较高,超过了 5 就高,超过了 10 就不正常了;

  • bi 和 bo 一般都要接近 0,不然就是 IO 过于频繁


[root@svr01]$ vmstat 1 3procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st0  0 206944 633564  29876 1252176    0    0    10    27    0    0  1  1 98  0  00  0 206944 634232  29876 1252192    0    0     0     0  811 1504  1  1 98  0  00  0 206944 634480  29876 1252264    0    0     0     0  951 1458  6  1 93  0  0
复制代码

uptime

最近 1 分钟,5 分钟,15 分钟的系统平均负载。


  • <=3 则系统性能较好。

  • <=4 则系统性能可以,可以接收。

  • 大于 5 则系统性能负载过重,可能会发生严重的问题,那么就需要扩容了,要么增加核心数量


[root@svr01]$ uptime21:27:44 up 207 days, 11:15, 1 user, load average: 26.45, 16.76, 7.50
复制代码

top

主要看 us 和 sy,其中 us<=70,sy<=35,us+sy<=70 说明状态良好,同时可以结合 idle 值来看,如果 id<=70 则表示 IO 的压力较大。

4.2 Memory 指标

vmstat

  • swpd:虚拟内存已使用的大小,如果大于 0,表示你的机器物理内存不足了

  • si:每秒从磁盘读入虚拟内存的大小,如果这个值大于 0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。

  • so:每秒虚拟内存写入磁盘的大小,如果这个值大于 0,同上,单位为 KB。


[root@svr01]$ vmstat 1 3procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st0  0 206944 633564  29876 1252176    0    0    10    27    0    0  1  1 98  0  00  0 206944 634232  29876 1252192    0    0     0     0  811 1504  1  1 98  0  00  0 206944 634480  29876 1252264    0    0     0     0  951 1458  6  1 93  0  0
复制代码

Disk 指标

df

Use%:已使用占比,Use% <= 90% 表示还勉强接受正常


  [root@svr01]$ df  Filesystem           1K-blocks     Used Available Use% Mounted on  /dev/mapper/VolGroup00-LVroot 17737040  4286920  12542448  26% /  tmpfs                  1893300        0   1893300   0% /dev/shm  /dev/sda1               194241   127341     56660  70% /boot  /dev/mapper/VolGroup00-LVhome487652     2348    459704   1% /home  /dev/mapper/VolGroup00-LVcloud3030800   260440   2613076  10% /opt/cloud  /dev/mapper/VolGroup00-LVtmp  8125880    18724   7687728   1% /tmp  /dev/mapper/VolGroup00-LVvar 25671996   848996  23512280   4% /var  /dev/mapper/VolGroup1-LVdata1  41149760 33707952   5344864  87% /wls/applogs  
复制代码

Disk IO 指标

sar -d 1 1:查看磁盘报告 1 1 表示间隔 1s,运行 1 次


  • 如果 svctm 的值与 await 很接近,表示几乎没有 I/O 等待,磁盘性能很好,如果 await 的值远高于 svctm 的值,则表示 I/O 队列等待太长,系统上运行的应用程序将变慢。

  • 如果 %util 接近 100%,表示磁盘产生的 I/O 请求太多,I/O 系统已经满负荷的在工作,该磁盘请求饱和,可能存在瓶颈。

  • idle 小于 70% I/O 压力就较大了,也就是有较多的 I/O。


  [root@svr01]$ sar -d 1 1  Linux 2.6.32-642.6.2.el6.x86_64 (SHB-L0044551) 07/20/2018 _x86_64_ (1 CPU)
03:00:23 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util 03:00:24 PM dev252-0 23.00 808.00 80.00 38.61 9.88 375.35 43.48 100.00 03:00:24 PM dev252-16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 03:00:24 PM dev253-0 4.00 448.00 0.00 112.00 1.11 222.00 249.50 99.80 03:00:24 PM dev253-1 50.00 400.00 0.00 8.00 24.40 523.20 20.00 100.00 03:00:24 PM dev253-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 03:00:24 PM dev253-3 3.00 32.00 0.00 10.67 0.99 242.33 331.67 99.50 03:00:24 PM dev253-4 0.00 0.00 0.00 0.00 1.61 0.00 0.00 100.00 03:00:24 PM dev253-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 03:00:24 PM dev253-6 3.00 0.00 24.00 8.00 1.30 393.67 261.33 78.40
Average: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util Average: dev252-0 23.00 808.00 80.00 38.61 9.88 375.35 43.48 100.00 Average: dev252-16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: dev253-0 4.00 448.00 0.00 112.00 1.11 222.00 249.50 99.80 Average: dev253-1 50.00 400.00 0.00 8.00 24.40 523.20 20.00 100.00 Average: dev253-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: dev253-3 3.00 32.00 0.00 10.67 0.99 242.33 331.67 99.50 Average: dev253-4 0.00 0.00 0.00 0.00 1.61 0.00 0.00 100.00 Average: dev253-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: dev253-6 3.00 0.00 24.00 8.00 1.30 393.67 261.33 78.40
复制代码

4Network IO 指标

netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn


在不考虑系统负载、CPU、内存等情况下,netstat 监控大量 ESTABLISHED 连接与 Time_Wait 连接


[root@svr01]$ netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn265 TIME_WAIT 45 ESTABLISHED 38 CLOSE_WAIT 18 LISTEN  8 FIN_WAIT2  2 SYN_SENT  1 Foreign  1 established)
复制代码

关于统计的量化指标

注意:有些命令通用,有些是我根据系统的日志文件格式利用 awk/sed 两个命令结合写出来的。


  1. netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn ( 查看 TCP 连接状态 )

  2. netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20( 查找较多 time_wait 连接 )

  3. netstat -anlp|grep tcp |awk '{print 5}' |awk -F':' '{print 1}' |uniq -c |sort -nr | head -n3( 查出访问靠前的 IP 地址 )

  4. cat hmilyylimh_sql.log | awk '{print 6}' | awk -F'ms' '{print 1}' | awk -F'=' '{print $2 | "sort -r -n" }' | head -n5( 查询 sql 文件中耗时最高的前 5 个耗时数据值 )

  5. cat hmilyylimh_supp.log | awk '{print 10}' | awk -F'timeConsuming=' '{print 2 }' | awk -F'ms' '{print $1 | "sort -r -n" }' | head -n5( 查看 supp 文件中耗时最高的前 5 个耗时数据值 )

  6. cat hmilyylimh_sql.log | grep 'sql:=' | awk '{print $5}' | uniq -c | sort -rn | head -n2( 查询 sql 文件总共打印了多少条 SQL 日志 )

  7. cat hmilyylimh_sql.log | grep 'NormalTimeConsuming' | awk '{print $5}' | uniq -c | sort -rn | head -n2( 查看 sql 文件成功执行了多少条 SQL 日志 )

  8. cat hmilyylimh_sql.log | grep 'BadTimeConsuming' | awk '{print $5}' | uniq -c | sort -rn | head -n2( 查看 sql 文件失败或者异常执行了多少条 SQL 日志 )

  9. cat hmilyylimh_supp.log | grep 'sendReqSupp start'| awk '{print 7$8}' | uniq -c | sort -nr | head -n2( 查询 supp 文件 sendReqSupp start 字符串出现的次数 )

  10. lsof -n | awk '{print 2}' | sort | uniq -c | sort -nr | head -n10( 统计持有各个进程持有句柄数最高的 10 个 )

  11. lsof -n | awk '{print 2}' | sort | uniq -c | sort -nr | awk '{ sum+=$1 };END { print sum } '( 计算所有进程持有句柄数的总和,ulimit -n 命令查看最大句柄数 )

  12. lsof | awk 'NF == 9 { print $0}' | sort +6 -7nr | head -n10( 查看系统打开的大文件列表 )

  13. top -b -n 1 | grep -E 'Cpu(s)|Mem|Swap'( 一次性查出系统当前的 CPU、内存、交换区的情况 )

  14. iostat -p sda | awk -F'Device' '{ print $1 }'( 查看 cpu 的统计信息(平均值) )

  15. cat access_log.date +%Y%m%d.txt | awk '{print $6}' | uniq -c | sort -k2 -r | head -n10( 统计每秒请求并发,按照时间降序排列 )

  16. cat access_log.date +%Y%m%d.txt | awk '{print $6}' | uniq -c | sort -rn | head -n10( 统计每秒并发,按照并发量降序排列 )

  17. cat access_log.date +%Y%m%d.txt | awk '{ sum+=$NF }; END { print sum*2/8/1024/1024, "M" }'( 查看访问 hmilyylimh 服务器每天的总流量 )

  18. cat gc.log | tail -n20|awk '{print 4}'| awk -F'->' '{print 1, 3 }'| awk -F'(' '{print 2, 3}' | awk -F')' '{print 1}' | awk -F'K' '{print 3100, "% used -> " ,3100, "% used " , 100-3*100, "% free ", $3/1024, "M total --- 新生代" }'( 查看 gc 指标,新生代最后 n 条记录的新生代内存变化率 )

  19. cat gc.log | tail -n20 | awk '{print 7}' | awk -F'->' '{print 1, 3 }' | awk -F'(' '{print 2, 3}' | awk -F')' '{print 1}' | awk -F'K' '{print 3100, "% used -> " ,3100, "% used " , 100-3*100, "% free ", $3/1024, "M total --- 堆内存" }'( 查看最后 10 条 GC 日志的堆内存已使用转化率 )

  20. cat /etc/sysctl.conf | grep 'tcp_'( 查看 TCP 参数设置信息 )

  21. cat hmilyylimh.log | awk '{if(0}' | grep "max_user_connections" | wc -l( 查看具体时间点后某个字符串出现的次数 )

六、系统常用计数器命令

1、echo "<<<<<<<<<<<<<< 线程阻塞等待计数: "`less hmilyylimh_error.log | grep "with callerRunsPolicy" | wc -l`",   ""db事务嵌套锁AcquireLock计数: "`less hmilyylimh_error.log | grep "CannotAcquireLockException" | wc -l`",   ""创建事务异常计数: "`less hmilyylimh_error.log | grep "CannotCreateTransactionException" | wc -l`",    ""db连接池溢出计数: "`less hmilyylimh_error.log | grep "more than 'max_user_connections'" | wc -l`",    ""Pool Empty计数: "`less hmilyylimh_error.log | grep "Unable to fetch a connection" | wc -l`" >>>>>>>>>>>>>>"
2、echo "<<<<<<<<<<<<<< UnknownHostException计数: "`less hmilyylimh_error.log | grep "UnknownHostException" | wc -l`", ""ConnectionPoolTimeout计数: "`less hmilyylimh_error.log | grep "ConnectionPoolTimeout" | wc -l`", ""ConnectException计数: "`less hmilyylimh_error.log | grep "ConnectException" | wc -l`", ""ConnectTimeoutException计数: "`less hmilyylimh_error.log | grep "ConnectTimeoutException" | wc -l`", ""SocketTimeoutException计数: "`less hmilyylimh_error.log | grep "SocketTimeoutException" | wc -l`", ""OtherException计数: "`less hmilyylimh_error.log | grep "OtherException" | wc -l`" >>>>>>>>>>>>>>"
3、echo "<<<<<<<<<<<<<< Sql耗时最高的前5个数值: "`cat hmilyylimh_sql.log | awk '{print $6}' | awk -F'ms' '{print $1}' | awk -F'=' '{print $2 | "sort -r -n" }' | head -n5`", ""Supp耗时最高等待前5个数值: "`cat hmilyylimh_supp.log | awk '{print $10}' | awk -F'timeConsuming=' '{print $2 }' | awk -F'ms' '{print $1 | "sort -r -n" }' | head -n5`" >>>>>>>>>>>>>>"
4、echo "<<<<<<<<<<<<<< Http请求耗时最高前10个数值: "`less hmilyylimh.log | grep "timeConsuming=" | awk '{print $9}' | awk -F'=' '{print $2}' | awk -F'ms' '{print $1 | "sort -r -n" }' | head -n10`" >>>>>>>>>>>>>>"
复制代码


发布于: 2022 年 01 月 30 日阅读数: 3
用户头像

浩宇天尚

关注

🏆InfoQ写作平台-签约作者🏆 2020.03.25 加入

【个人简介】酷爱计算机科学、醉心编程技术、喜爱健身运动、热衷悬疑推理的“极客达人” 【技术格言】任何足够先进的技术都与魔法无异 【技术范畴】Java领域、Spring生态、MySQL专项、微服务/分布式体系和算法设计等

评论

发布
暂无评论
【优化技术专题】「系统性能调优实战」终极关注应用系统性能调优及原理剖析(上册)