步骤

作者: Daisy小朋友 | 来源:发表于2020-03-06 16:21 被阅读0次
吞吐量

https://time.geekbang.org/column/article/87342

应用监控

应用程序的监控,可以分为指标监控和日志监控两大部分:

指标监控:

主要是对一定时间段内性能指标进行测量,然后再通过时间序列的方式,进行处理、存储和告警。

日志监控:

则可以提供更详细的上下文信息,通常通过 ELK 技术栈来进行收集、索引和图形化展示。

ELK 技术栈中的 Logstash 资源消耗比较大。所以,在资源紧张的环境中,我们往往使用资源消耗更低的 Fluentd,来替代 Logstash(也就是所谓的 EFK 技术栈)。
ELK中采集端还可以使用filebeat,整个架构可以拓展为filebeat-kafka(zookeeper)-logstash或sparkstreaming-es。除了可以做日志查询之外可以做业务关联等

构建全链路跟踪系统:

这样可以动态跟踪调用链中各个组件的性能,生成整个流程的调用拓扑图,从而加快定位复杂应用的性能问题
全链路跟踪可以帮你迅速定位出,在一个请求处理过程中,哪个环节才是问题根源。比如,从上图中,你就可以很容易看到,这是 Redis 超时导致的问题。全链路跟踪除了可以帮你快速定位跨应用的性能问题外,还可以帮你生成线上系统的调用拓扑图。这些直观的拓扑图,在分析复杂系统(比如微服务)时尤其有效
Zipkin、Jaeger、Pinpoint 等各类开源工具,来构建全链路跟踪系统


image.png
最近在使用skywalking这个全链路监控系统,感觉比日志监控什么好太多了
链路监控和日志监控的目标不一样,一个是跨组件的整体监测,一个是单组件的详细细节,通常是互补的
一 CPU
image.png
当你收到系统的用户 CPU 使用率过高告警时,从监控系统中直接查询到,导致 CPU 使用率过高的进程;然后再登录到进程所在的 Linux 服务器中,分析该进程的行为。你可以使用 strace,查看进程的系统调用汇总;也可以使用 perf 等工具,找出进程的热点函数;甚至还可以使用动态追踪的方法,来观察进程的当前执行过程,直到确定瓶颈的根源。
1 top
2 vmstat 5
是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析CPU上下文切换和中断的次数
3 pidstat -w 5
专门分析每个进程CPU使用情况的工具
4 strace -p <pid>
strace 正是最常用的跟踪进程系统调用的工具

参考:https://www.cnblogs.com/kongzhongqijing/articles/4913192.html

5 perf top
它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以分析指定应用程序的性能问题。是内置于linux内核源码数中的性能剖析工具,常用于性能瓶颈的查找和热点代码的定位
perf top主要是用于分析各个函数在某个性能事件上的热度,能够快速的定位热点函数,包括应用程序函数

二 内存
image.png

我们可以通过 free 和 vmstat 输出的性能指标,确认内存瓶颈;然后,再根据内存问题的类型,进一步分析内存的使用、分配、泄漏以及缓存等,最后找出问题的来源。
比如说,当你收到内存不足的告警时,首先可以从监控系统中。找出占用内存最多的几个进程。然后,再根据这些进程的内存占用历史,观察是否存在内存泄漏问题。确定出最可疑的进程后,再登录到进程所在的 Linux 服务器中,分析该进程的内存空间或者内存分配,最后弄清楚进程为什么会占用大量内存

1 free
2 top
3 vmstat 3
关注内存变化趋势
4 memleak
用来检测内存泄漏的工具,以跟踪系统或指定进程的内存分配、释放请求,然后定期输出一个未释放内存和相应调用栈的汇总情况(默认 5 秒),memleak 是 bcc 软件包中的一个工具,执行 /usr/share/bcc/tools/memleak 就可以运行它
注意:bcc-tools 需要内核版本为 4.1 或者更高,如果你使用的是 CentOS7,或者其他内核版本比较旧的系统,那么你需要手动升级内核版本后再安装

三 磁盘和文件系统
image.png

当你发现某块磁盘的 I/O 使用率为 100% 时,首先可以从监控系统中,找出 I/O 最多的进程。然后,再登录到进程所在的 Linux 服务器中,借助 strace、lsof、perf 等工具,分析该进程的 I/O 行为。最后,再结合应用程序的原理,找出大量 I/O 的原因。
1 top 查看cpu的iowaite高不高
2 iostat -d -x 1 查看相关指标 iotop 排序

- %util ,就是我们前面提到的磁盘 I/O 使用率;
- r/s+ w/s ,就是 IOPS;
- rkB/s+wkB/s ,就是吞吐量;
- r_await+w_await ,就是响应时间。

3 pidstat -d 1
查看是那个进程导致大量io读写
4 strace+ lsof查看具体是进程中那个环境导致
strace -f -p 27458
mysql是多线程,-f可以查看线程,查看到线程28014正常大量读取
lsof -p 27458 后面加进程查看
查看到strace中38描述符对应的文件/var/lib/mysql/test/products.MYD,表示test数据库中products表的读写
那就是在 MySQL 命令行界面中,执行 show processlist 命令,来查看当前正在执行的 SQL 语句
检查具体语句,确认没有使用索引导致全盘扫描,导致慢查询

strace 基于系统调用 ptrace 实现,这就带来了两个问题。
由于 ptrace 是系统调用,就需要在内核态和用户态切换。当事件数量比较多时,繁忙的切换必然会影响原有服务的性能;
ptrace 需要借助 SIGSTOP 信号挂起目标进程。这种信号控制和进程挂起,会影响目标进程的行为。
所以,在性能敏感的应用(比如数据库)中,我并不推荐你用 strace (或者其他基于 ptrace 的性能工具)去排查和调试
在 strace 的启发下,结合内核中的 utrace 机制, perf 也提供了一个 trace 子命令,是取代 strace 的首选工具。
相对于 ptrace 机制来说,perf trace 基于内核事件,自然要比进程跟踪的性能好很多
perf trace 的使用方法如下所示,跟 strace 其实很像:

$ perf trace ls
         ? (         ): ls/14234  ... [continued]: execve()) = 0
     0.177 ( 0.013 ms): ls/14234 brk(                                                                  ) = 0x555d96be7000
     0.224 ( 0.014 ms): ls/14234 access(filename: 0xad98082                                            ) = -1 ENOENT No such file or directory
     0.248 ( 0.009 ms): ls/14234 access(filename: 0xad9add0, mode: R                                   ) = -1 ENOENT No such file or directory
     0.267 ( 0.012 ms): ls/14234 openat(dfd: CWD, filename: 0xad98428, flags: CLOEXEC                  ) = 3
     0.288 ( 0.009 ms): ls/14234 fstat(fd: 3</usr/lib/locale/C.UTF-8/LC_NAME>, statbuf: 0x7ffd2015f230 ) = 0
     0.305 ( 0.011 ms): ls/14234 mmap(len: 45560, prot: READ, flags: PRIVATE, fd: 3                    ) = 0x7efe0af92000
     0.324 Dockerfile  test.sh
( 0.008 ms): ls/14234 close(fd: 3</usr/lib/locale/C.UTF-8/LC_NAME>                          ) = 0
     ...
perf trace 还可以进行系统级的系统调用跟踪(即跟踪所有进程),而 strace 只能跟踪特定的进程
image.png

参考:
https://time.geekbang.org/column/article/78633
https://www.jianshu.com/p/ab9bdf346fae
https://time.geekbang.org/column/article/86710

四 网络性能分析
image.png
1 ping
ping 是一种最常用的网络工具,常用来探测网络主机之间的连通性以及延迟
2 traceroute --tcp -p 80 -n baidu.com
跟踪数据包到达网络主机所经过的路由工具
3 查询域名解析
time nslookup time.geekbang.org加time可以看到时间
查看dns路径以及ip
$ dig +trace +nodnssec time.geekbang.org
+trace表示开启跟踪查询
+nodnssec表示禁止DNS安全扩展
4 tcpdump 抓包,后用 Wireshark 分析
终端1抓包:tcpdump -nn host 93.184.216.34 -w web.pcap
终端2触发: curl https://www.baidu.com

tcpdump抓包可以用来处理一些疑难问题的。 如受到了什么类型的攻击,执行了mysql的什么命令,接收以及发送出去了什么数据包通通都可以。像入侵检测如snort工具之类的应该也是对数据包进行抓包分析的,很实用,很强大
之前公司一个内部应用出现页面卡顿,而且每次都是1-2用户反馈(随机),排出了应用本身,服务器,客户端网络问题后,然后让it在用户端抓包传给我,然后用Wireshark分析后,发现有大量虚假重传,后面分析后发现,是用户都在一个Nat网络后面,部分用户时间不一致,同时我们服务器开启了tcp快速回收,导致连接被回收了。后面关闭tcp快速回收后解决。也是第一次用工具分析这种比较复杂的问题。

参考:https://www.dell.com/community/%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E8%AE%A8%E8%AE%BA%E5%8C%BA/%E5%A6%82%E6%9E%9C%E7%9C%8B%E4%BA%86%E8%BF%99%E4%B8%AA%E4%BD%A0%E8%BF%98%E6%98%AF%E4%B8%8D%E4%BC%9A%E7%94%A8Wireshark-%E9%82%A3%E5%B0%B1%E6%9D%A5%E6%89%BE%E6%88%91%E5%90%A7-8%E6%9C%886%E6%97%A5%E5%AE%8C%E7%BB%93/td-p/7007033
5 Web的问题推荐 MITM,F12使用

非权威查询结果

Non-authoritative answer:
Name: time.geekbang.org
Address: 39.106.233.17

五 应用程序瓶颈分析

除了以上这些来自网络资源的瓶颈外,还有很多瓶颈,其实直接来自应用程序。比如,最典型的应用程序性能问题,就是吞吐量(并发请求数)下降、错误率升高以及响应时间增大。不过,在我看来,这些应用程序性能问题虽然各种各样,但就其本质来源,实际上只有三种,也就是资源瓶颈、依赖服务瓶颈以及应用自身的瓶颈。第一种资源瓶颈,其实还是指刚才提到的 CPU、内存、磁盘和文件系统 I/O、网络以及内核资源等各类软硬件资源出现了瓶颈,从而导致应用程序的运行受限。对于这种情况,我们就可以用前面系统资源瓶颈模块提到的各种方法来分析。第二种依赖服务的瓶颈,也就是诸如数据库、分布式缓存、中间件等应用程序,直接或者间接调用的服务出现了性能问题,从而导致应用程序的响应变慢,或者错误率升高。这说白了就是跨应用的性能问题,使用全链路跟踪系统,就可以帮你快速定位这类问题的根源。最后一种,应用程序自身的性能问题,包括了多线程处理不当、死锁、业务算法的复杂度过高等等。对于这类问题,在我们前面讲过的应用程序指标监控以及日志监控中,观察关键环节的耗时和内部执行过程中的错误,就可以帮你缩小问题的范围。不过,由于这是应用程序内部的状态,外部通常不能直接获取详细的性能数据,所以就需要应用程序在设计和开发时,就提供出这些指标,以便监控系统可以了解应用程序的内部运行状态。如果这些手段过后还是无法找出瓶颈,你还可以用系统资源模块提到的各类进程分析工具,来进行分析定位。比如:你可以用 strace,观察系统调用;使用 perf 和火焰图,分析热点函数;甚至使用动态追踪技术,来分析进程的执行状态。当然,系统资源和应用程序本来就是相互影响、相辅相成的一个整体。实际上,很多资源瓶颈,也是应用程序自身运行导致的。比如,进程的内存泄漏,会导致系统内存不足;进程过多的 I/O 请求,会拖慢整个系统的 I/O 请求等。所以,很多情况下,资源瓶颈和应用自身瓶颈,其实都是同一个问题导致的,并不需要我们重复分析

另附录CPU
 安装
yum -y  install  dstat
vmstat
yum -y install  sysstat(pidstat  iostat)
pidtsat 
yum -y install dstat(perf pidstat)
strace不用安装
perf  yum -y install perf
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st 
0  0      0 7005360  91564 818900    0    0     0     0   25   33  0  0 100 
cs(context switch)是每秒上下文切换的次数。
in(interrupt)则是每秒中断的次数。
r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
b(Blocked)则是处于不可中断睡眠状态的进程数。
# 每隔5秒输出1组数据
$ pidstat -w 5
Linux 4.15.0 (ubuntu)  09/23/18  _x86_64_  (2 CPU)
08:18:26     UID       PID   cswch/s nvcswch/s  Command
08:18:31        0         1      0.20      0.00  systemd
08:18:31        0         8      5.40      0.00  rcu_sched
cswch  ,表示每秒自愿上下文切换(voluntary context switches)的次数
nvcswch  ,表示每秒非自愿上下文切换(non voluntary context switches)的次数
[root@VM_2_220_centos ~]# strace -cp 5199
Process 5199 attached
^CProcess 5199 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.53    0.629904       17997        35           poll
  0.47    0.003000        3000         1           restart_syscall
  0.00    0.000000           0        36           accept
  0.00    0.000000           0        72           setsockopt
  0.00    0.000000           0         3           clone
  0.00    0.000000           0       108           fcntl
  0.00    0.000000           0        39           gettimeofday
  0.00    0.000000           0        60           futex
------ ----------- ----------- --------- --------- ----------------
100.00    0.632904                   354           total
[root@VM_2_220_centos ~]# strace -T -e poll -p 5199
Process 5199 attached
poll([{fd=16, events=POLLIN}, {fd=22, events=POLLIN}], 2, -1) = 1 ([{fd=16, revents=POLLIN}]) <0.006130>
poll([{fd=16, events=POLLIN}, {fd=22, events=POLLIN}], 2, -1) = 1 ([{fd=16, revents=POLLIN}]) <13.663980>
poll([{fd=16, events=POLLIN}, {fd=22, events=POLLIN}], 2, -1) = 1 ([{fd=16, revents=POLLIN}]) <4.531740>
poll([{fd=16, events=POLLIN}, {fd=22, events=POLLIN}], 2, -1) = 1 ([{fd=16, revents=POLLIN}]) <21.465710>
poll([{fd=16, events=POLLIN}, {fd=22, events=POLLIN}], 2, -1) = 1 ([{fd=16, revents=POLLIN}]) <0.006329>
poll([{fd=16, events=POLLIN}, {fd=22, events=POLLIN}], 2, -1^CProcess 5199 detached
# -g开启调用关系分析,-p指定php-fpm的进程号21515
$ perf top -g -p 21515
按方向键切换到 php-fpm,再按下回车键展开 php-fpm 的调用关系,你会发现,调用关系最终到了 sqrt 和 add_function。看来,我们需要从这两个函数入手了
具体看CPU高排查里面的使用

相关文章

网友评论

      本文标题:步骤

      本文链接:https://www.haomeiwen.com/subject/wjimfhtx.html