写点什么

服务器性能竟然可以这样展示

  • 2019-10-25
  • 本文字数:2532 字

    阅读完需:约 8 分钟

服务器性能竟然可以这样展示

在项目开发中,经常会遇到程序启动时间过长、CPU 使用率过高等问题,这个时候需要依靠性能分析工具来定位性能的消耗点。本文介绍三个常用的工具的入门级使用及图形化方法,供大家参考。


本文介绍 Perf、gprof 和 Valgrind 三个性能分析工具,及其分析结果图形化的方法,旨在让大家更快的上手使用工具。出于篇幅的限制,本文不会对每种工具的使用参数及结果分析做详细的介绍,只做入门级的使用说明,更多详细的说明大家请 Google 一下。


每个工具的介绍会分成简介、使用说明、图形化方法三个部分。

每种工具的结果都会基于下面这段代码:

#include <unistd.h>using namespace std;#define NUM 500000void init(int* int_array){  for(int i=0;i<NUM;i++){    int_array[i]=i;  }}void accu(int* int_array,long& sum ){  for(int i=0;i<NUM;i++){    sum+=int_array[i];    usleep(3);  }  }int main(){  int int_array[NUM];  init(int_array);  long sum=0;  accu(int_array,sum);}
复制代码


这段代码在普通 PC 上执行了 31s,最大 CPU 使用率为 8.3%

Perf

1.1 简介

Perf 是内置于 Linux 内核源码树中的性能剖析(profiling)工具。其基于事件采样原理,以性能事件为基础,常用于性能瓶颈的查找与热点代码的定位。

1.2 使用

perf 的使用可以分为两种方式:


1.直接使用 perf 启动服务


2.挂接到已启动的进程


第一种方式不需要 root 权限,第二种方式需要 root 权限


基于入门级使用这一前提,直接介绍一下使用方式:


perf record -e cpu-clock -g ./run


或者


perf record -e cpu-clock -g -p 4522


使用 ctrl+c 中断 perf 进程,或者在程序执行结束后,会产生 perf.data 的文件,使用


perf report


会产生结果分析,如图


1.3 图形化方法

perf 的结果可以生成火焰图。生成火焰图需要借助 Flame Graph


Flame Graph 项目位于 GitHub:Flame Graph


clone 代码或者直接下载压缩包到服务器上。以压缩包为例,是一个命名为:FlameGraph-master.zip 的文件,假设其解压后的目录为:/data


基于 1.2 产生的 perf.data,后续步骤如下:


1、使用 perf script 工具对 perf.data 进行解析


perf script -i perf.data &> perf.unfold


2、将 perf.unfold 中的符号进行折叠:/data/stackcollapse-perf.pl perf.unfold &> perf.folded


3、最后生成 svg 图:/data/flamegraph.pl perf.folded > perf.svg


生成的火焰图如下:



关于火焰图的含义及分析网上有很多文章,这里不再赘述

Gprof

2.1 简介

gprof 用于监控程序中每个方法的执行时间和被调用次数,方便找出程序中最耗时的函数。在程序正常退出后,会生成 gmon.out 文件,解析这个文件,可以生成一个可视化的报告

2.2 使用方法

使用 gprof,需要在编译时,加入-pg 选项


另外只有在程序正常退出后才会生成 gmon.out,kill 进程的方法是没法生成 gmon.out 的。对于那些线程会一直 run 的服务,需要修改代码,让程序在某个时间点停止。


重新编译后,正常启动程序即可;然后在程序运行结束后,会生成 gmon.out 文件


使用如下命令,生成报名文件(其中 run 是二进制的名字):


gprof -b run gmon.out >>report.txt


report.txt 打开如下图所示:


2.3 图形化方法

gprof 的结果文件需要借助 gprof2dot.py 和 graphviz 来展示


使用 gprof2dot.py 生成 dot 文件


python gprof2dot.py report.txt >report.dot


需要说明的是,这里要求服务器已经安装了 python,并且要求 gprof2dot.py 与安装的 python 版本匹配。这两者是否匹配是一个需要运气、并且解决起来很无聊的事情,我的服务器上安装的 python 是 2.6.6,第一次从网上下载的 gprof2dot-2017.9.19 与 python 版本就不匹配,执行会出错。目前使用的版本与 2.6.6 是兼容的,如果需要可以与我联系。


dot 的打开需要 graphviz 工具,我是在 windows 下安装的 graphviz,这个工具下载很简单。下载后使用 gvedit.ext 打开前一个步骤产生的 report.dot 文件即可



这个图显的有些萌萌哒,这是因为我们的程序写的比较简单,对于一般的业务而言,这个图会比较复杂。

Valgrind

3.1 简介

valgrind 不是 linux 的原生工具,需要自行安装。valgrind 自身包含了多个工具:


  • Memcheck:用于内存泄漏检查

  • Callgrind:用于性能分析,会收集程序运行时间和调用关系

  • 以及 Cachegrind、Helgrind 等


这里我们主要使用的 Callgrind 工具

3.2 使用方法

首先需要安装valgrind


解压安装包后,顺次执行:./configue 、make、make install 就可以了


使用 valgrind 来分析性能,必须使用 valgrind 来启动程序:


valgrind --tool=callgrind --separate-threads=yes ./run


–separate-threads 是指是否按线程来分别统计,如果不加,会将所有线程的结果打到一个文件里;否则会按线程分别打印到不同文件里。


程序执行结束后,会生成形如:callgrind.out.4263-01 的文件。这个文件直接分析起来有些困难,必须借助图形化的方式来浏览

3.3 图形化方法

valgrind 的图形化需要借助 kcachegrind.exe,大家可以自行下载,下载后在 windows 运行即可。这是打开 callgrind.out.4263-01 的结果:


工具比较

对于我们的需求:定位执行时间最长、占用 CPU 最多的函数 来说,这三个工具都可以达到目的。但这三者之间还是有一定的差距:

4.1 启动方式

Perf 虽然可以挂接进程但需要 root 权限。在普通权限下,Perf 和 Valgrind 必须使用前缀启动的方式来启动程序,这在某种程度上会影响到程序的性能。我们在压测的过程中发现使用 Valgrind 启动的时候,可以支持的在线总人数比直接运行程序要少很多。

4.2 程序侵入

Perf 和 Valgrind 都不需要修改 Makefile 或者程序,但 gprof 需要重新编译文件,并且对于线程一直 run 的服务,还需要修改代码让其自然退出,这在一定程序上侵入了程序。但从对性能影响上来看,gprof 可以最大限制的保留原程序的性能

4.3 结果展示

gprof 的结果是一颗倒树,这颗树展示了从根到叶子的所有结点的时间消耗;perf 的是一个金字塔,与 gprof 有异曲同工之妙;Valgrind 的结果是一条单路,指出的是某条调用路径上的时间消耗,并不是一个全局的展示。

4.4 监控原理

这是一个很专业的话题,目前对三者的监控原理还没有摸的太透,所以这里暂时空着。大家有兴趣可以先行研究。


本文转载自公众号云加社区(ID:QcloudCommunity)。


原文链接:


https://mp.weixin.qq.com/s/gKE8AbuqCLG0RwFVdWZS8Q


2019-10-25 18:13709

评论

发布
暂无评论
发现更多内容

leetcode练级-两数之和

幸福三寸日光

算法 LeetCode js

Spring Security密码登录流程源码分析

读钓

源码分析 spring security springboot

从引用聊一聊 Java 垃圾回收

Rayjun

Java 引用 对象

RabbitMQ-AMQP

云淡风轻

RabbitMQ

时间管理的本质

史方远

职场 心理 成长

k8s 上运行我们的 springboot 服务之——我们的springboot能够在k8s上运行

柠檬

k8s istio springboot

使用 webpack 搭建一个简单的 React 脚手架

张张张小烦

react.js

k8s上运行我们的springboot服务之——cloud gateway

柠檬

k8s Spring Cloud

《零基础学 Java》 FAQ 之 12-理解引用

臧萌

Java

其实你就是我羡慕的别人

小天同学

个人成长 感悟 日常思考

MySQL实战四十五讲基础篇总结(四)

一个有志气的DB

MySQL 索引结构

MySQL实战四十五讲基础篇总结(七)

一个有志气的DB

MySQL 性能

谈谈控制感(9):提升控制感排名第一的武器

史方远

职场 心理 成长

Java 数据持久化系列之JDBC

程序员历小冰

Java JDBC 持久化

Go: Trace包探秘

陈思敏捷

原理 Go 语言

你是个伪工作者么?

池建强

个人成长 伪工作者

2020 年 5 月 23 日 Java 集合专题

瑞克与莫迪

Java

除了直接看余额,谁更有钱还能怎么比(一)

石君

零知识证明 多方计算 同态加密

云直播平台的选型与使用

音视频专家-李超

Java环境搭建

编号94530

Java java8 Java环境 环境安装 jdk安装

Tekton 的工作原理

张晓辉

Kubernetes cicd 云原生

【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

一枝花算不算浪漫

并发编程 jdk源码 线程池

谈谈我的云笔记使用之路

读钓

学习 个人成长 写作

利与弊-传统框架要不要部署在Serverless架构上

刘宇

Serverless Web

我的编程之路 -5(停滞)

顿晓

网络编程 操作系统 编程之路 停滞 三年

工作=投资=创业?

二鱼先生

个人成长 工作思路 工作方式 创业心态 创业者

MySQL实战四十五讲基础篇总结(五)

一个有志气的DB

MySQL 索引

谈即时编译优化-以异常堆栈丢失为例

寻筝

Go: 应该使用指针还是结构体副本?

陈思敏捷

struct 原理 pointer Go 语言

MySQL实战四十五讲基础篇总结(六)

一个有志气的DB

MySQL 读写锁

python实现·十大排序算法之快速排序(Quick Sort)

南风以南

Python 排序算法 快速排序

服务器性能竟然可以这样展示_文化 & 方法_赵坤_InfoQ精选文章