SpringBoot3+Micormeter监控应用指标
监控内容简介
SpringBoot3项目监控服务 ,可以使用Micormeter度量指标库,帮助我们监控应用程序的度量指标,并将其发送到Prometheus中并用Grafana展示。监控指标有系统负载、内存使用情况、应用程序的响应时间、吞吐量、错误率等。
micrometer 度量指标库,对springboot应用程序监控指标的采集主要体现在JVM的众多的监控项。
1. JVM 常用监控指标
2. JVM监控项详解
序号 | 指标 | 类型 | 含义 | 原文 |
---|---|---|---|---|
1 | logback_events_total | counter | 记录到日志的错误级别事件数 | Number of error level events that made it to the logs |
2 | system_cpu_usage | gauge | 整个系统的“最近cpu使用情况” | The "recent cpu usage" for the whole system |
3 | system_load_average_1m | gauge | 系统负载 | The sum of the number of runnable entities queued to available processors and the number of runnable entities running on the available processors averaged over a period of time |
4 | system_cpu_count | gauge | java虚拟机可用的处理器数量 | The number of processors available to the Java virtual machine |
5 | process_start_time_seconds | gauge | 自unix时代以来进程的开始时间(秒) | Start time of the process since unix epoch. |
6 | process_cpu_usage | gauge | java虚拟机进程的“最近CPU使用” | The "recent cpu usage" for the Java Virtual Machine process |
7 | process_uptime_seconds | gauge | java虚拟机的运行时间 | The uptime of the Java virtual machine |
8 | process_files_open_files | gauge | 打开文件描述符数量 | The open file descriptor count |
9 | process_files_max_files | gauge | 最大文件描述符数量 | The maximum file descriptor count |
10 | tomcat_sessions_expired_sessions_total | counter | tomcat过期会话数总计 | |
11 | tomcat_sessions_rejected_sessions_total | counter | tomcat拒绝会话数总计 | |
12 | tomcat_sessions_active_max_sessions | gauge | tomcat_活跃会话最大数量 | |
13 | tomcat_sessions_created_sessions_total | counter | tomcat会话创建会话总数 | |
14 | tomcat_sessions_active_current_sessions | gauge | tomcat当前活跃会话数 | |
15 | tomcat_sessions_alive_max_seconds | gauge | 最大tomcat会话存活时间 | |
16 | jvm_classes_loaded_classes | gauge | Java虚拟机中当前加载的类数 | The number of classes that are currently loaded in the Java virtual machine |
17 | jvm_classes_unloaded_classes_total | counter | 未加载的classes数 | The total number of classes unloaded since the Java virtual machine has started execution |
18 | jvm_memory_used_bytes | gauge | 内存使用大小 | The amount of used memory |
19 | jvm_memory_max_bytes | gauge | 可用于内存管理的字节的最大内存量 | The maximum amount of memory in bytes that can be used for memory management |
20 | jvm_memory_committed_bytes | gauge | 提交给Java虚拟机使用的内存量(字节) | The amount of memory in bytes that is committed for the Java virtual machine to use |
21 | jvm_buffer_memory_used_bytes | gauge | JVM缓冲区已用内存 | An estimate of the memory that the Java virtual machine is using for this buffer pool |
22 | jvm_buffer_total_capacity_bytes | gauge | 缓冲区的总容量的估计 | An estimate of the total capacity of the buffers in this pool |
23 | jvm_buffer_count_buffers | gauge | 当前缓冲区数 | An estimate of the number of buffers in the pool |
24 | jvm_gc_pause_seconds | summary | GC暂停时间 | Time spent in GC pause |
25 | jvm_gc_pause_seconds_max | gauge | GC最大暂停时间 | Time spent in GC pause |
26 | jvm_gc_max_data_size_bytes | gauge | 老年代内存池的最大大小 | Max size of old generation memory pool |
27 | jvm_gc_memory_allocated_bytes_total | counter | 在一次GC之后到下一次GC之前,年轻一代内存池的大小增加 | Incremented for an increase in the size of the young generation memory pool after one GC to before the next |
28 | jvm_gc_live_data_size_bytes | gauge | full GC后的老年代内存池大小 | Size of old generation memory pool after a full GC |
29 | jvm_gc_memory_promoted_bytes_total | counter | 从GC之前到GC之后老年代内存池大小正增长的计数 | Count of positive increases in the size of the old generation memory pool before GC to after GC |
30 | jvm_threads_states_threads | gauge | 当前处于NEW状态的线程数 | The current number of threads having NEW state |
31 | jvm_threads_live_threads | gauge | 当前活动线程数,包括守护进程线程和非守护进程线程 | The current number of live threads including both daemon and non-daemon threads |
32 | jvm_threads_daemon_threads | gauge | 当前守护进程线程的数量 | The current number of live daemon threads |
33 | jvm_threads_peak_threads | gauge | JVM峰值线程数 | The peak live thread count since the Java virtual machine started or peak was reset |
34 | http_server_requests_seconds | summary | http请求调用情况 | |
35 | http_server_requests_seconds_max | gauge |
3. 指标在运维中的使用
3.1. JVM 基本信息概述
Start time: JVM启动时间 - 即:根据该指标可以知道目前程序启动的时间
Uptime: JVM运行时间 - 即:根据该指标可以知道目前程序运行时长
3.2. I/O Detail
JVM中的IO操作是应用程序中非常重要的一部分,因此需要监控和衡量相应的指标来保证系统的正常运行。
Rate 图中的: QPS :每秒查询率,是一台服务器每秒能够响应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
简单的说,QPS = req/sec = 请求数/秒。它代表的是服务器的机器的性能最大吞吐能力。
Duration 图中:AVG:指Average Latency 平均等待时间,请求处理时长(min:最小值,max:最大值,avg:平均值,current:实时)
JVM中IO衡量指标的详细解释和问题定位场景的举例:
- I/O吞吐量 I/O吞吐量指的是应用程序进行I/O操作的速度,可以通过监控I/O操作的完成时间和I/O操作的数量来计算。如果I/O吞吐量过低,可能会导致系统性能下降。
- 问题定位场景:如果应用程序需要进行大量的I/O操作,可以通过监控相应的I/O吞吐量指标来确定是否存在性能问题。
- I/O延迟 I/O延迟指的是应用程序进行I/O操作的响应时间,可以通过监控I/O操作的完成时间和I/O操作的数量来计算。如果I/O延迟过高,可能会导致系统性能下降。
- 问题定位场景:如果应用程序需要进行大量的I/O操作,可以通过监控相应的I/O延迟指标来确定是否存在性能问题。
- 文件打开数量 文件打开数量指的是应用程序同时打开的文件数量,可以通过监控文件描述符的数量来计算。如果文件打开数量过高,可能会导致系统资源耗尽。
- 问题定位场景:如果应用程序需要同时打开大量的文件,可以通过监控相应的文件打开数量指标来确定是否存在系统资源不足的问题。
- 缓冲区使用量 缓冲区使用量指的是应用程序使用缓冲区的情况,可以通过监控缓冲区大小和缓冲区使用情况等指标来计算。如果缓冲区使用量过低或者过高,可能会导致I/O性能下降。
- 问题定位场景:如果应用程序需要频繁地使用缓冲区,可以通过监控相应的缓冲区使用量指标来确定是否存在性能问题。
- 网络连接数量 网络连接数量指的是应用程序同时打开的网络连接数量,可以通过监控网络连接的数量和网络连接的状态等指标来计算。如果网络连接数量过高,可能会导致系统资源耗尽。
- 问题定位场景:如果应用程序需要同时打开大量的网络连接,可以通过监控相应的网络连接数量指标来确定是否存在系统资源不足的问题。 综上所述,对于JVM中的IO操作,可以通过监控相应的指标来定位问题场景,并采取相应的优化措施来提高系统性能。
3.3. JVM Memory - JVM内存
3.3.1. 过滤项
java虚拟机把堆内存划分为三个区域:年轻代,老年代,和永久代. 1,年轻代: 年轻代又分为一个Eden区和两个Survivor区(一个from Survivor和一个to Survivor),每次只会使用Eden和其中一个Survivor区,这么分配的原因是年轻代采用了”复制”算法来回收.当创建新的对象时,(大部分情况下)这个对象所占的空间会在Eden区分配,如果Eden区的空闲空间不足,这时虚拟机会触发一次Minor GC,将Eden区和from Survivor区中还存活的对象转移到to Survivor区中. 在经历若干次Minor GC之后,如果对象还是存活,那就会被移到老年代中去. 2,老年代(old) 存放系统中长期存活的对象,比如通过spring托管的一些单例对象,如service对象,dao对象等.还有一部分是在Minor GC后年轻代的空间仍然不足时,从年轻代转移过来的对象,这部分对象一般是导致系统发生Full GC的主要原因. 3,永久代(perm) 存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.
3.3.2. 当前堆内存利用率
Heap Used: 堆内存使用率; 根据:堆内存已使用(字节)/ 堆内存大小(字节) 计算得出
Non-Heap used: 堆外内存使用率; 根据: 堆外内存已使用(字节)/ 堆外内存大小(字节) 计算得出
常见问题:
内存使用率高;长时间达到70% 以上;
当应用程序中堆内存使用率一致很高,且不下降时。势必造成程序中的内存资源耗尽,出现卡死情况;
可以根据老年代使用率来查看;如使用率超过90%;
其他常见问题:
场景一:内存溢出,JVM堆区或方法区放不下存活及待申请的对象。如:高峰期系统出现 OOM(Out of Memory)异常,需定位内存瓶颈点来指导优化。
场景二:内存泄漏,不会再使用的对象无法被垃圾回收器回收。如:系统运行一段时间后出现 Full GC,甚至周期性 OOM 后需人工重启解决。
场景三:内存占用高。如:系统频繁 GC ,需定位影响服务实时性、稳定性、吞吐能力的原因。
问题分析(出现的问题有):
1、内存分配的问题
2、长期持有supersql big 对象消耗内存
3、死锁问题
4、poll长连接较多或者其他导致兵法线程增多
具体问题分析参照下述监控指标
3.3.3. 概念:
JVM Memory指标的详细解释和生产环境中如何定位问题场景的举例: JVM Memory指标包括以下几个方面:
- JVM Heap Memory:堆内存是JVM中存放对象实例的内存区域,通常是JVM中最重要的内存区域。Heap Memory指标可分为以下几个维度:
- heap.used:已使用的堆内存大小
- heap.committed:已提交的堆内存大小
- heap.max:最大可用的堆内存大小
2. JVM Non-Heap Memory:非堆内存指的是JVM中存放类信息、方法信息、常量等数据的内存区域。Non-Heap Memory指标可分为以下几个维度:
- nonheap.used:已使用的非堆内存大小
- nonheap.committed:已提交的非堆内存大小
- nonheap.max:最大可用的非堆内存大小
3. JVM Total JVM 内存使用总量
- used是已经被使用的内存大小
- committed是当前可使用的内存大小(包括已使用的)committed >= used。committed不足时jvm向系统申请,若超过max则发生OutOfMemoryError错误。
- max是内存最大值。
3.3.4. 通过监控这些JVM Memory指标,可以定位生产环境中的一些问题场景,例如:
- 内存泄漏:如果Heap Memory的used值持续增长,而非释放,可能存在内存泄漏问题。可以通过监控Heap Memory的used值,定位内存泄漏问题的代码位置。
- 内存溢出:如果Heap Memory的used值已经达到了Max值,并且还在持续增长,可能存在内存溢出问题。可以通过监控Heap Memory的used值和Max值,定位内存溢出问题的代码位置。
- 内存分配频繁:如果Eden内存池的used值持续增长,而Survivor内存池的used值持续较低,可能存在内存分配频繁问题。可以通过监控Memory Pool的used值,定位内存分配频繁问题的代码位置。
综上所述,通过监控Micrometer中的JVM Memory指标,可以定位生产环境中的一些内存问题,进而采取相应的优化措施提高系统性能。
3.4. JVM Memory Pools(Heap)
- Memory Pool:内存池是JVM中管理内存的一种机制,内存池可以分为Eden、Survivor、Old等。
PS Eden Space:新生代
PS Old Gen:老年代
一般情况新创建的对象会放到新生代中,只有经过一定次数的GC后还没有被回收的对象,我们认为这部分对象在未来也会长时间存在,所以会把这部分的对象转移到老年代的区域中去。
PS Survivor Space:新生代
GC把垃圾对象回收后如果不对存活下来的对象进行整理,那么就会出现很多不连续的内存空间,这也就是我们常说的空间碎片,因为没有连续的空间分配,这样就可能造成我们一个大对象过来我们没有对应的连续空间分配,但是内存里其实是有能够容纳对象的总空间的。
所以为了减少这种空间碎片,我们就使用了另一种方式,把新生代分为了Eden 区和Survior 区,在进行垃圾回收时,先把存活的对象复制到 Survior 区,然后再对Eden区统一进行清理,这样的话Eden区每次GC过后都是留下的一片连续的空间。
2. Memory Pool指标可分为以下几个维度:
- pool.used:已使用的堆内存大小。表示当前已经分配给Java堆内存空间的大小。
- pool.committed:已提交的堆内存大小。表示Java堆内存的最大可用空间,也就是-Xmx参数指定的最大堆内存值。
- pool.max:最大可用的堆内存大小。表示当前JVM实例中可用的最大堆内存大小,一般是物理内存的一部分。
- Init:初始堆内存大小。表示JVM启动时分配给Java堆的内存空间大小,一般是-Xms参数指定的初始堆内存值。
通过监控JVM Memory Pools(Heap)指标,我们可以发现以下问题:
- 内存溢出:如果Used指标持续增长,并且已经接近或达到Max指标的值,那么就可能发生了内存溢出。可以通过增加-Xmx参数来扩大堆内存的容量,或者优化代码以减少内存使用。
- 内存泄漏:如果Used指标持续增长,而Committed指标没有变化,那么就可能发生了内存泄漏。可以通过内存分析工具来查找内存泄漏的原因,并进行修复。
- GC频繁:如果Used指标的波动较大,而且频率较高,那么就可能发生了GC频繁的问题。可以通过调整GC策略或优化代码来减少GC的发生。
综上所述,通过监控JVM Memory Pools(Heap)指标,我们可以及时发现和解决Java应用程序中的内存问题,提高系统性能。
3.5. JVM Memory Pools(Non-Heap)
JVM Memory Pools(Non-Heap)指标用于监控Java应用程序的非堆内存使用情况,包括Metaspace、Code Cache、Compressed Class Space等。它提供了多个维度的指标,可以帮助我们深入了解Java非堆内存的使用状况,发现问题并进行针对性的优化。
非堆内存也叫做PermGen space(永久代),与新生代和老年代概念对齐,就是说是永久保存的区域, 用于存放Class和Meta信息,Class在被Load的时候被放入该区域,GC应该不会对PermGen space进行清理。
3.5.1. 概念
- Metaspace: 元空间
- 元空间包含类的其它比较大的元数据,比如方法,字节码,常量池等。
- Compressed Class Space类指针压缩空间
- 类指针压缩空间只包含类的元数据,比如InstanceKlass, ArrayKlass 仅当打开了UseCompressedClassPointers选项才生效 为了提高性能,Java中的虚方法表也存放到这里 这里到底存放哪些元数据的类型,目前仍在减少
- Code Cache 代码缓存区
- 用于编译和保存本地代码
3.5.2. JVM Memory Pools(Non-Heap)指标的详细解释和定位问题的举例:
- Committed:已提交的非堆内存大小。表示Java非堆内存的最大可用空间。
- Max:最大可用的非堆内存大小。表示当前JVM实例中可用的最大非堆内存大小,一般是物理内存的一部分。
- Used:已使用的非堆内存大小。表示当前已经分配给Java非堆内存空间的大小。
- Init:初始非堆内存大小。表示JVM启动时分配给Java非堆的内存空间大小。 通过监控JVM Memory Pools(Non-Heap)指标,我们可以发现以下问题:
- 内存溢出:如果Used指标持续增长,并且已经接近或达到Max指标的值,那么就可能发生了内存溢出。可以通过增加-Xmx参数来扩大非堆内存的容量,或者优化代码以减少内存使用。
- 内存泄漏:如果Used指标持续增长,而Committed指标没有变化,那么就可能发生了内存泄漏。可以通过内存分析工具来查找内存泄漏的原因,并进行修复。
- 类加载频繁:如果Metaspace指标持续增长,而且频率较高,那么就可能发生了类加载频繁的问题。可以通过调整类加载机制或优化代码来减少类加载的发生。
综上所述,通过监控JVM Memory Pools(Non-Heap)指标,我们可以及时发现和解决Java应用程序中的非堆内存问题,提高系统性能。
3.5.3. 以往问题排查思路及步骤
服务内存占用过高的原因排查思路:
- 服务启动时分配的堆内存过小(与Xms和Xmx有关,-Xms 为JVM启动时申请的初始Heap值,-Xmx 为JVM运行时可申请的最大Heap值)
- 具有大量大对象被创建,并且没有及时被GC回收或者由于具有引用GC无法回收(代码中存在不合理的地方,需要进行代码调优)
- 当GC之后,虽然会清理堆内的对象看,但是并不会释放内存,没有把曾经申请到的内存归还给操作系统(与垃圾回收器和垃圾回收器的回收机制有关)
相关命令:
1、free -m # 查看内存使用情况,后面加个m是以M为单位显示
2、查看哪几个进程内存占用最高:top -c,输入大写M,以内存使用率从高到低排序
VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
3、通过jmap -heap 进程id 命令排除是由于堆分配内存问题
jmap -heap 21114
4. 查看进程中占用资源最大的前20个对象(主要在对应程序启用用户下执行)
jmap -histo:live 19424 |head -20
5. jstat查看进程的内存使用情况
jstat -gcutil 19424
现在:可以根据上述监控指标得出,并且配合log中定位代码存在不合理情况
log中查看
一般情况下出现下列异常可直接定位: 堆溢出: java.lang.OutOfMemoryError:Java heap spcace 栈溢出: java.lang.StackOverflowError 方法区溢出: java.lang.OutOfMemoryError:PermGen space
3.6. JVM Misc
3.6.1. CPU Usage:cpu 利用率
system: CPU花了多少比例的时间在内核空间运行。分配内存、IO操作、创建子进程……都是内核操作
3.6.2. load: 负载均衡
cpu负载:负载表示的是“等待进程的平均数”,运行态(running)和不可中断状态(interruptible)才会被加入到负载等待进程中,具体为下面两种情况:
- 即便需要立即使用CPU,也还需等待其他进程用完CPU
- 即便需要继续处理,也必须等待磁盘输入输出完成才能进行
3.6.3. Threads:线程计数。
- live: 当前活动线程数(包括守护线程和非守护线程);
- damon threads:守护线程(当前活动后台的线程)
- 守护线程又称为“服务线程”。在没有用户线程可服务时会自动离开。非守护线程的优先级比较低,用于为系统中的其它对象和线程提供服务。
- 垃圾回收线程就是一个经典的守护线程,当我们的程序中不再有任何运行的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是JVM上仅剩的线程时,垃圾回收线程会自动离开。它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源。
- peak threads:峰值线程数
3.6.4. Threads Stats: 状态,参照下图理解:
NEW:尚未启动的线程的线程转台
RUNNABLE:可运行线程的线程状态。线程在运行或者正在获取CPU时间片
BLOCKED:线程的线程状态被阻止,正在等待监视器锁。
WAITING:等待线程的线程状态。
TIMED_WAITING:具有指定等待时间的等待线程的线程状态。调用某个线程的具有指定正等待时间的方法时,所处于指定等待时间的等待线程的线程状态。
TERMINATED:终止线程的线程状态。
3.6.5. Log Events
每分钟上报的日志数量
3.6.6. File Descriptors 描述文件
file descriptors是一个非负整数,一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。
程序打开一个现有文件或者创建一个新文件,内核向该进程返回一个文件描述符。
open: JVM当前打开的文件描述符数;
max: JVM进程最大可以打开的文件描述符数;
常见问题:
java应用程序,频繁的IO读写,创建过多的线程,CPU都会较高,而线程死锁或者死循环基本是导致cpu高的原因。
后台常用命令:
jstack -1 pid # 打印进程的对战信息,结合代码查找占用CPU的问题。
3.7. Garbage Collection
Garbage Collection指标用于监控Java应用程序的垃圾回收情况
3.7.1. 相关概念:
collections图:
1、Metadata GC threshold是指元数据空间的GC阈值。在JVM中,元数据空间是用来存储Java类信息、常量池、方法信息等元数据的空间。当元数据空间满了之后,就会触发元数据空间的GC,回收无用的元数据信息。 Metadata GC threshold指标用于监控元数据空间的GC阈值。当元数据空间的使用率超过了阈值,就会触发元数据空间的GC。Metadata GC threshold指标可以用来监控元数据空间的使用情况,以及GC对元数据空间的影响程度。
a)end of minor GC:表示minor GC结束的时间戳,即新生代垃圾回收结束的时间戳。在JVM中,新生代的GC次数远远多于老年代,因此用end of minor GC指标来刻画新生代GC的情况。end of minor GC指标可以用来监控新生代GC的频率和时间间隔,以及GC的效率和吞吐量。
b) end of major GC:表示major GC结束的时间戳,即老年代垃圾回收结束的时间戳。在JVM中,老年代的GC次数比新生代少,但是GC的影响更大,因此用end of major GC指标来刻画老年代GC的情况。end of major GC指标可以用来监控老年代GC的频率和时间间隔,以及GC的效率和吞吐量。
2) ops/sec: 每秒操作数
3) allocation failure:表示在GC过程中出现内存分配失败的次数。allocation failure指标可以用来监控内存的使用情况,以及GC对内存使用的影响程度。如果allocation failure指标持续增长,就说明内存不足,可能需要增加堆内存或优化程序的内存使用方式。
pause durations图:
表示GC暂停的时间。GC暂停是指在GC期间应用程序的执行被中断了,这段时间内应用程序无法执行任何操作。
pause durations指标可以用来监控GC的效率和吞吐量,以及GC对应用程序的影响程度。
Allocated/Promoted图:
1)allocated表示当前GC周期中新生代分配的对象大小;
2)promoted表示当前GC周期中老年代晋升的对象大小;
allocated/promoted指标可以用来监控垃圾回收的内存使用情况,以及GC对内存使用的影响程度。
3.7.2. 通过监控Garbage Collection指标,我们可以发现以下问题:
- GC频繁:在生产环境中,如果Metadata GC threshold指标持续增长(end of minor GC 和end of major GC),就说明元数据空间的使用率过高,可能会影响应用程序的性能。可以通过增加元数据空间的大小或优化程序的元数据使用方式来减少元数据空间的GC。如果元数据空间的使用率过高,还可能会导致OutOfMemoryError异常,需要及时进行调优。
- 内存不足:如果allocation failure指标持续增长,就说明内存不足,可能需要增加堆内存或优化程序的内存使用方式。
- 内存泄漏:如果Collection Count指标持续增长,而Committed指标没有变化,那么就可能发生了内存泄漏。可以通过内存分析工具来查找内存泄漏的原因,并进行修复。
- GC效率低: pause durations指标可以用来监控GC的效率和吞吐量,以及GC对应用程序的影响程度。
综上所述,通过监控Garbage Collection指标,我们可以及时发现和解决Java应用程序中的垃圾回收问题,提高系统性能。
3.8. Classloading
Class loaded 和 Class delta是Java虚拟机(JVM)的两个指标,用于衡量JVM加载和卸载类的情况。
Class loaded 指标表示JVM自启动以来已经加载的类的总数。这个指标可以用来判断应用程序是否存在类加载过多的问题。如果Class loaded指标的增长速度太快,那么就可能存在内存泄漏或者类重复加载等问题。
Class delta 指标表示自上次垃圾回收以来,类加载器动态加载和卸载的类的数量。这个指标可以用来判断应用程序是否存在类加载和卸载不平衡的情况。如果Class delta指标的值过大,说明有太多的类被加载和卸载,可能会导致JVM性能下降。
综合来说,Class loaded和Class delta指标可以用来监控JVM的类加载和卸载状况,帮助开发人员发现和解决可能存在的性能问题。
3.9. Buffer Pools
DirectBuffer和MappedByteBuffer是Java NIO(New IO)中的两种缓冲区类型,用于进行内存映射和直接内存访问。这两种缓冲区类型在不同的场景下具有不同的衡量指标和定位问题的方法。
DirectBuffer衡量指标:
- 内存使用量:通过监控DirectBuffer的内存使用量,可以了解应用程序使用直接内存的情况。如果内存使用量过高,可能会导致内存泄漏或者OutOfMemoryError等问题。
- 分配速度:通过监控DirectBuffer的分配速度,可以了解应用程序使用直接内存的频率。如果分配速度过快,可能会导致内存分配和回收的开销过大,从而降低系统性能。
- 回收速度:通过监控DirectBuffer的回收速度,可以了解应用程序释放直接内存的情况。如果回收速度过慢,可能会导致内存泄漏或者OutOfMemoryError等问题。 MappedByteBuffer衡量指标:
- 内存使用量:通过监控MappedByteBuffer的内存使用量,可以了解应用程序使用内存映射的情况。如果内存使用量过高,可能会导致内存泄漏或者OutOfMemoryError等问题。
- I/O性能:通过监控MappedByteBuffer的I/O性能,可以了解应用程序使用内存映射的性能。如果I/O性能过低,可能会导致系统性能下降。
- 缓存命中率:通过监控MappedByteBuffer的缓存命中率,可以了解应用程序使用内存映射的缓存情况。如果缓存命中率过低,可能会导致I/O次数过多,从而降低系统性能。 定位问题场景:
- 如果应用程序需要频繁地读写大量的数据,可以考虑使用DirectBuffer来进行内存操作。
- 如果应用程序需要使用大量的内存映射文件,可以考虑使用MappedByteBuffer来进行内存操作。
- 如果应用程序存在内存泄漏或者性能问题,可以通过监控相应的指标来定位问题,并采取相应的优化措施。例如,通过减少直接内存的使用量或者优化内存映射的使用方式等方式来提高系统性能。
Micrometer 实现应用监控并将监控数据发送到 Prometheus
在 Spring Boot 应用中使用 Micrometer 实现应用监控并将监控数据发送到 Prometheus 是一个常见的监控解决方案。Micrometer 是一个应用监控工具,它能够无缝地与多种监控系统(如 Prometheus、Grafana 等)集成。
整理 by https://zhengkai.blog.csdn.net/
以下是实现步骤:
步骤 1: 添加依赖
在你的 pom.xml 中添加 Micrometer 和 Prometheus 的依赖。
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
步骤 2: 配置 application.yml
在 application.yml 文件中配置 Micrometer 和 Spring Actuator。
spring:
application:
name: my-spring-boot-app
actuator:
endpoints:
web:
exposure:
include: "*"
metrics:
export:
prometheus:
enabled: true
步骤 3: 创建控制器
创建一个简单的控制器,以便你可以测试监控数据。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
步骤 4: 启动 Prometheus
确保你的机器上已经安装了 Prometheus,并通过以下示例配置文件启动它。
prometheus.yml
global:
scrape_interval: 5s # 每5秒抓取一次
scrape_configs:
- job_name: 'my-spring-boot-app' # 自定义的 job 名称
metrics_path: '/actuator/prometheus' # Micrometer 提供的 Prometheus 监控端点
static_configs:
- targets: ['localhost:8080'] # 你的 Spring Boot 应用地址
步骤 5: 启动应用并测试
- 启动你的 Spring Boot 应用。
- 启动 Prometheus(确保 Prometheus 配置文件路径正确)。
prometheus --config.file=prometheus.yml
- 访问你的应用接口,例如 http://localhost:8080/hello。
- 访问 Prometheus UI,通常是 http://localhost:9090。
- 在 Prometheus UI 中,你可以通过查询 http_requests_total 等指标来查看你的应用监控数据。
步骤 6: 查看监控
在 Prometheus UI 中,你可以输入 http_requests_total 或其他相关指标进行查询,查看你的应用的请求数量、响应时间等统计信息。
总结
通过以上步骤,你已经成功地将 Spring Boot 应用的监控数据集成到 Prometheus 中。Micrometer 作为监控库,提供了丰富的功能,可以帮助你监控应用的各个方面。你可以根据自己的需求,进一步扩展和自定义监控指标。
原文地址:https://blog.csdn.net/moshowgame/article/details/144307157
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!