应用的性能相关的指标有哪些?

原文在这里: 应用的性能相关的指标有哪些?
扫一扫加关注【爪哇优太儿】
现如今连天气都可以预报,那么通过技术手段来预测应用的性能和可用性是否可行呢?预计未来20分钟总可以吧?能否预计出来未来20分钟以内应用可能会发生内存溢出、CPU负载飙升、应用崩溃?很不幸大部分时候都无法预测。这主要因为我们主要是关注应用的内存使用率、CPU使用率、响应时间等宏观指标,但是还有很多其他的微观指标也会影响预测应用的性能和可用性,本文就来探讨下影响应用性能和可用性的那些微观指标。

首先看第一个例子:
在这里插入图片描述
上图中可以看到有连续的FullGC。这个应用最后出现了内存溢出,我们来看下堆使用率的图,可以看出来即使是经过了很多次的FullGC但是内存的占用还是一直在增高,应用在8点左右出现FullGC,在10点左右出现了内存溢出,从8点到10点应用一直不停的做FullGC,如果运维团队监控发现了这个问题,他们本可以在几个小时前就能预测出来应用可能会内存溢出。

内存相关的微观指标

有4个内存和垃圾回收相关的微观指标:GC的吞吐量、GC的最大停顿时间、对象创建的速度、占用的最大堆空间。下面分别来看下:

1.GC的吞吐量

GC的吞吐量是说应用花在执行业务代码上的时间与花在执行垃圾回收所用时间的占比,比如说应用运行了60分钟,其中2分钟用来做垃圾回收,那么应用花在GC上的时间就是2/60=3.33%,也就是说GC的吞吐量就是96.67%。当吞吐量下降的时候,应用可能就出问题了。

2.GC的最大停顿时间

在这里插入图片描述
GC过程的某些阶段是需要暂停整个应用的,这个暂停也叫延迟。有些GC可能只花费几个毫秒,但是有些可能会花费数秒甚至数分钟。你需要监控GC的停顿时间,停顿时间长会影响用户的体验。

3.对象创建的速度

在这里插入图片描述
对象创建的速度就是应用中创建的对象数量和大小,比如你的应用的对象创建速度是每秒100M,在网络流量没有变大的情况下最近忽然变成150M,那么很有可能你的应用出问题了。多创建出来的对象会触发更多的GC、增加CPU时间、影响响应时间。

这个也可以用来衡量最近提交的代码的质量,之前的代码,每秒创建50M对象,最近提交了新的代码以后,应用每秒创建75M对象,说明最近提交了一些低效的代码。

4.最大堆空间

在这里插入图片描述
最大堆空间就是应用占用的最大的堆内存,如果这个最大值超过了限度,就需要查找下原因了,应用很有可能存在内存泄漏,可能是新提交的代码或者是三方库占用了大量的内存。

如何拿到内存相关的指标数据?

所有内存相关的指标数据都可以从GC日志中拿到。可以给JVM传递如下参数启用GC日志:

java8之前:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:

java9以后:

-Xlog:gc*:file=

只要拿到了GC日志,就可以手动用GC日志分析工具来对日志做分析,也可以用调用日志分析REST接口编程来分析。如果想把这个过程自动化的话那么REST接口就很有用了,同时还可以用在项目的持续集成中。

看下第二个例子:

有个大型财务应用运行几个小时以后,出现“内存溢出,无法创建本地线程”错误。这个应用在JDBC驱动上启用了一个新的特性,显然,这个特性有bug,由于这个bug导致JDBC驱动不停的创建新的线程而不是重用之前的线程,因此,一段时间以后就出现了上面的错误。如果监控到了线程的数量和状态,本来是可以提早发现并且预防这个问题的。下图是应用的线程dump,可以看出来两个dump之间,RUNNABLE的线程数量是在持续增长的:
在这里插入图片描述

线程相关的微观指标

有4个线程相关的微观指标:线程数量、线程状态、线程组、线程执行模式。

5.线程数量

线程数量是一个很有趣的指标,如果线程数量过大会引起CPU、内存问题甚至是应用崩溃,线程数量过大会导致“内存溢出,无法创建本地线程”错误,因此如果线程数持续增加,应用很可能出问题了。

6.线程状态

在这里插入图片描述
应用中的线程有6种状态:NEW、RUNNABLE、WAITING、TIMED_WAITING、BLCKED、TERMINATED。太多的线程都是RUNNABLE会导致CPU负载飙高,太多线程是BLCKED会导致应用无响应,如果应用中某种状态的线程数超过了正常该有数量,那就是应用性能可能出问题的预兆。

7.线程组

在这里插入图片描述
线程组就是做相同任务的一组线程。比如Servlet容器有个线程组来处理所有的HTTP请求,比如JMS线程组处理JMS的发送和接收,应用中还可能有其他的线程组。你要监控这些线程组的大小,即不能太大也不能太小,太少会导致任务积压,太多会导致CPU内存问题。

8.线程执行模式

在这里插入图片描述
如果大量的线程有相似的或者重复的堆栈那么很有可能有性能问题,比如以下的场景:

(a)应用依赖的一个外部服务变慢导致大量的线程都在等待服务的响应,这种情况下,这些线程的堆栈都是一样的。

(b)一个线程获取了锁以后一直没有释放,别的想获取这个锁的线程都会被阻塞,他们的堆栈也是一样的。

(c)如果应用有死循环,所有执行循环的线程都会出现相同的堆栈。

出现以上任何一种情况都会严重影响应用的性能和可用性。

如何拿到线程相关的指标数据?

所有线程相关的指标数据都可以从线程dump中获取。

有很多种获取线程dump的方法,可以选择对你最方便的一种,建议5-10秒钟dump一次。拿到了线程dump之后,就可以手动分析或者用调用REST接口来分析。

网络相关指标

网络相关的指标主要有3个:tcp/ip连接数、tcp/ip状态、打开的文件描述符的数量。

9.tcp/ip连接数

应用与外部应用之间一般都会有很多个连接,连接可能有很多不同的协议比如http、https、soap、rest、jdbc、jms等等,这种情况下,你的应用的可用性和性能是受限于外部系统的可用性和性能的。因此你需要监控你的应用和外部应用之间的这些连接。如果连接数忽然增加了可能就要出问题了。当外部应用变慢的时候,为了处理请求,你的应用可能就需要打开更多的到外部应用的连接。可以用netstat命令来查看到外部系统的连接数:

$ netstat -an | grep ESTABLISHED | grep '162.187.223.11' | wc -l

上面的命令列出了到162.187.223.11的连接数。

10.tcp/ip状态

总共有11种tcp/ip状态,LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT, CLOSED。你要监控每一种状态的连接数,如果某个状态的连接数增大,比如说CLOSE_WAIT或者LAST_ACK的连接数变大,你的应用很有可能有网络连接相关的问题。

11.打开的文件描述符的数量

文件描述符是用来访问:文件、管道(用消息传递的方式做跨进程通信时候的一种机制)、网络连接的句柄。如果应用打开的文件描述符数量增大很可能是应用没有正确的释放资源。文件描述符用完不关闭可能会导致性能和可用性问题。下面的命令列出了5666进程打开的所有文件描述符:

lsof -p 5666

如果想知道这些文件描述符的总数量,可以用如下命令:

 lsof -p 5666 | wc -l

存储相关指标

存储相关指标有3个:IOPS、存储的吞吐量、存储的延迟。

12.IOPS

IOPS就是每秒的IO数量,也就是说每秒完成的读写操作数。有些IO操作,IO请求的size可能很小,可能是4K、8K、32K。IO请求的size越大,IOPS越少。

13.存储的吞吐量

存储的吞吐量说明了存储可以发送的字节数,一般是个常量,用M/S来衡量,下面是计算吞吐量的公式:

平均的IO size * IOPS = 吞吐量

14.存储的延迟

每个IO请求都需要一定时间来完成,这个时间叫做平均延迟。一般用毫秒来衡量,通常都是非常低的。有很多因素会影响这个时间,很多时候都是受限于传统磁盘的物理结构。

数据库相关维度

本文主要是谈论应用层面的指标,监控数据库的指标也是非常有用的。数据库的指标主要有:数据库锁、慢查询、内存表被替换出内存、缓存命中率。

结论

在生产环境中可以通过监控这些维度来预测应用中可能发生的问题,此外,还可以用在持续集成中来监控代码的质量,希望这些维度对你有所帮助。

英文原文:https://blog.gceasy.io/2019/03/13/micrometrics-to-forecast-application-performance/

如果感觉有用,欢迎扫描开头二维码加关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值