分布式监控工具

1、Zabbix 的JMX监控架构

在Zabbix中,JMX监控数据的获取由专门的代理程序来实现,即Zabbix-Java-Gateway来负责数据的采集,Zabbix-Java-Gateway和JMX的Java程序之间通信获取数据.

工作原理:

zabbixserver想知道一台主机上的特定的JMX值时,它向ZabbixJavagateway询问,而ZabbixJavagateway使用“JMXmanagementAPI”去查询特定的应用程序,

而前提是应用程序这端在开启时需要“-Dcom.sun.management.jmxremote”参数来开启JMX查询就行了。

Zabbixserver有一个特殊的进程用来连接Javagateway叫StartJavaPollers;Javagateway通过配置文件中START_POLLERS参数设置启动多个线程,

在zabbix服务器这边如果一个连接所用时间超过Timeout,将会被中断,但是Javagateway将继续从JMXcounter取数据。所以

StartJavaPollers设置的值要小于等于START_POLLERS设置的值。

 2、prometheus

Prometheus 是由 SoundCloud 开发的开源监控报警系统和时序列数据库(TSDB).自2012年起,许多公司及组织已经采用 Prometheus,并且该项目有着

非常活跃的开发者和用户社区.现在已经成为一个独立的开源项目核,并且保持独立于任何公司,Prometheus 在2016加入 CNCF ( Cloud Native

Computing Foundation ), 作为在 kubernetes 之后的第二个由基金会主持的项目。

主要功能

多维 数据模型(时序由 metric 名字和 k/v 的 labels 构成)。

灵活的查询语句(PromQL)。

无依赖存储,支持 local 和 remote 不同模型。

采用 http 协议,使用 pull 模式,拉取数据,简单易懂。

监控目标,可以采用服务发现或静态配置的方式。

支持多种统计数据模型,图形化友好。

prometheus jmx exporter

jmx exporter是prometheus和JMX的桥梁。 

在我们的工程里面,它是以Java Agent的方式运行,它的功能是收集本地的JVM信息,并通过HTTP服务暴露出来。

> java -javaagent:./jmx_prometheus_javaagent-0.3.1.jar=8080:config.yaml -jar yourJar.jar

3、skywalking

Skywalking 是一个APM系统,即应用性能监控系统,为微服务架构和云原生架构系统设计。它通过探针自动收集所需的指标,并进行分布式追踪。

通过这些调用链路以及指标,Skywalking APM会感知应用间关系和服务间关系,并进行相应的指标统计。

总体架构分为三部分

skywalking-collector:链路数据归集器,数据可以落地ElasticSearch,单机也可以落地H2,不推荐,H2仅作为临时演示用

skywalking-web:web可视化平台,用来展示落地的数据

skywalking-agent:探针,用来收集和发送数据到归集器

图形界面集成工具

* 1、VisualVM:提供在Java 虚拟机(Java Virutal Machine, JVM) 上运行的Java 应用程序的详细信息

* 2、jConsole:Java 自带性能监控工具

* 3、TProfiler:阿里巴巴TProfiler是一个可以在生产环境长期使用的性能分析工具

* 4、ha456.jar:IBM HeapAnalyzer

* 5、BTrace:一个可以在不改代码、不重启应用的情况下,动态的查看程序运行细节的工具

* 6、MAT:MAT(Memory Analyzer Tool)(Eclipse Memory Analyzer),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗

命令行工具

 

1、jps 参考:[jps命令(Java Virtual Machine Process Status Tool)]()

> 查看本机当前登录用户的java进程,显示当前所有Java进程的pid

```bash

命令格式:jps [ options ] [ hostid ] 注:如果不指定hostid就默认为当前主机或服务器,如果需要查看其他机器上的jvm进程,需要在待查看机器上启动jstatd。

 

-q:只显示pid,不显示class名称,jar文件名和传递给main 方法的参数,仅输出VM标识符,不包括classname,jar name,arguments in main method

-m:输出传递给main 方法的参数,在嵌入式jvm上可能是null,输出main method的参数

-l:输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名,输出完全的包名,应用主类名,jar的完全路径名

-v:输出传递给JVM的参数,输出jvm参数

-V:输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件

-Joption:传递参数到vm,例如:-J-Xms512m

 

eg1:jps -m -l

```

2、jstack 参考:[jstack命令(Java Stack Trace)]()

> 主要用来查看某个Java进程内的线程堆栈信息, jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。

``` bash

命令格式:jstack [option] pid

 

-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况

-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)

```

 

#### 3、jmap 参考:[jmap命令(Java Memory Map)]()

> 用来查看或者导出堆内存使用状况,查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况,一般结合jhat使用

``` bash

命令格式:jmap [option] pid 注:如果运行在64位JVM上,可能需要指定-J-d64命令选项参数。

 

eg1:jmap -heap pid 注:显示堆内存分布使用情况

eg2:jmap -permstat pid 注:打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息

eg3:jmap -histo pid >>1.txt 注:查看pid中类的内存占用

eg4:jmap -dump:format=b,file=heap.bin 3676 注:把pid为3676的jvm进程内存镜像以二进制的方式保存到本地heap.bin文件

```

 

#### 4、jstat 参考:[jstat命令(Java Virtual Machine Statistics Monitoring Tool)()

> Jstat用于监控基于HotSpot的JVM,对其堆的使用情况进行实时的命令行的统计,使用jstat我们可以对指定的JVM做如下监控:

- 类的加载及卸载情况

- 查看新生代、老生代及持久代的容量及使用情况

- 查看新生代、老生代及持久代的垃圾收集情况,包括垃圾回收的次数及垃圾回收所占用的时间

- 查看新生代中Eden区及Survior区中容量及分配情况等

jstat工具特别强大,它有众多的可选项,通过提供多种不同的监控维度,使我们可以从不同的维度来了解到当前JVM堆的使用情况。详细查看堆内各个部分的使用量,使用的时候必须加上待统计的Java进程号,可选的不同维度参数以及可选的统计频率参数。

``` bash

命令格式:jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

 

eg1:jstat -gc 21711 250 4 注:pid为21711,采样时间间隔为250ms,采样数为4

 

1:堆内存 = 年轻代 + 年老代

2:年轻代 = Eden区 + 两个Survivor区(From和To)

 

各列含义:

1:S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)

2:EC、EU:Eden区容量和使用量

3:OC、OU:年老代容量和使用量

4:PC、PU:永久代容量和使用量

5:YGC、YGT:年轻代GC次数和GC耗时

6:FGC、FGCT:FullGC次数和Full GC耗时

7:GCT:GC总耗时

 

eg2:jstat -gcutil [pid] [internal(时间间隔)]

 

各列含义:

S0: Survivor space 0 区已使用空间的百分比

S1: Survivor space 1 区已使用空间的百分比

E: Eden space 区已使用空间的百分比

O: Old space 区已使用空间的百分比

P: Perm space 区已使用空间的百分比

YGC: Young GC 的次数

YGCT: Young GC 所用的时间 单位秒

FGC: Full GC 的次数

FGCT: Full GC 所用的时间 单位秒

GCT: 用于垃圾回收的总时间 单位秒

```

#### 5、jhat 参考:[ jhat命令(Java Heap Analyse Tool)]()

> Sun提供的内存镜像分析工具,是用来分析Java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言。

用于对JAVA heap进行离线分析的工具,他可以对不同虚拟机中导出的heap信息文件进行分析,如Linux上导出的文件可以拿到WINDOWS上进行分析,可以查找诸如内存方面的问题

```bash

第一步:导出堆 jmap -dump:format=b,file=heap.bin 15491

第二步:分析堆文件 jhat heap.bin

第三步:查看html http://localhost:7000/

 

注:有时你dump出来的堆很大,在启动时会报堆空间不足的错误,可以使用如下参数:jhat -J-Xmx512m <heap dump file>

```

 

#### 6、jinfo 参考:[jinfo命令(Java Configuration Info)]()

> 可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数。

```bash

命令格式:jinfo -opt pid

 

eg:jinfo -flag MaxPermSize 2788 查看2788的MaxPerm大小可以用

```

#### 7、jstatd 参考:[Jstatd命令(Java Statistics Monitoring Daemon)]():

> 一个基于RMI(Remove Method Invocation)的服务程序,它用于监控基于HotSpot的JVM中资源的创建及销毁,并且提供了一个远程接口允许远程的监控工具连接到本地的JVM执行命令。

jstatd是基于RMI的,所以在运行jstatd的服务器上必须存在RMI注册中心,如果没有通过选项"-p port"指定要连接的端口,jstatd会尝试连接RMI注册中心的默认端口。

后面会谈到如何连接到一个默认的RMI内部注册中心,如何禁止默认的RMI内部注册中心的创建,以及如何启动一个外部注册中心。

 

```bash

eg1:下面这个示例演示了通过内部RMI注册中心启动jstatd,这个示例假设没有其它的服务绑定到默认的RMI注册中心端口(默认端口是1099)。

jstatd -J-Djava.security.policy=jstatd.all.policy

```


其他注意的地方:

* 尽量减少Full GC的次数, 因为Full GC的消耗要比Monitor GC要大

* 年轻代大小: 尽可能设大, 降低年轻代GC次数, 同时也减少达到老年代的对象?

* 分配堆栈的最小值最好等于最大值, 因为动态分配也是需要耗费时间的. 如年轻代, 老年代, 持久代的最小最大值可设为一致