使用Prometheus+Alertmanager告警JVM异常情况

原文地址在前一篇文章中提到了如何使用Prometheus+Grafana来监控JVM。本文介绍如何使用Prometheus+Alertmanager来对JVM的某些情况作出告警。本文所提到的脚本可以在这里下载。摘要用到的工具:Docker,本文大量使用了Docker来启动各个应用。Prometheus,负责抓取/存储指标信息,并提供查询功能,本文重点使用它的告警功能。Grafana,负责数据可视化(本文重点不在于此,只是为了让读者能够直观地看到异常指标)。Alertmanager,负责将告警通知给相关人员。JMX exporter,提供JMX中和JVM相关的metrics。Tomcat,用来模拟一个Java应用。先讲一下大致步骤:利用JMX exporter,在Java进程内启动一个小型的Http server配置Prometheus抓取那个Http server提供的metrics。配置Prometheus的告警触发规则heap使用超过最大上限的50%、80%、90%instance down机时间超过30秒、1分钟、5分钟old gc时间在最近5分钟里超过50%、80%配置Grafana连接Prometheus,配置Dashboard。配置Alertmanager的告警通知规则告警的大致过程如下:Prometheus根据告警触发规则查看是否触发告警,如果是,就将告警信息发送给Alertmanager。Alertmanager收到告警信息后,决定是否发送通知,如果是,则决定发送给谁。第一步:启动几个Java应用1) 新建一个目录,名字叫做prom-jvm-demo。2) 下载JMX exporter到这个目录。3) 新建一个文件simple-config.yml内容如下:—blacklistObjectNames: [":"]4) 运行以下命令启动3个Tomcat,记得把<path-to-prom-jvm-demo>替换成正确的路径(这里故意把-Xmx和-Xms设置的很小,以触发告警条件):docker run -d \ –name tomcat-1 \ -v <path-to-prom-jvm-demo>:/jmx-exporter \ -e CATALINA_OPTS="-Xms32m -Xmx32m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.3.1.jar=6060:/jmx-exporter/simple-config.yml" \ -p 6060:6060 \ -p 8080:8080 \ tomcat:8.5-alpinedocker run -d \ –name tomcat-2 \ -v <path-to-prom-jvm-demo>:/jmx-exporter \ -e CATALINA_OPTS="-Xms32m -Xmx32m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.3.1.jar=6060:/jmx-exporter/simple-config.yml" \ -p 6061:6060 \ -p 8081:8080 \ tomcat:8.5-alpinedocker run -d \ –name tomcat-3 \ -v <path-to-prom-jvm-demo>:/jmx-exporter \ -e CATALINA_OPTS="-Xms32m -Xmx32m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.3.1.jar=6060:/jmx-exporter/simple-config.yml" \ -p 6062:6060 \ -p 8082:8080 \ tomcat:8.5-alpine5) 访问http://localhost:8080|8081|8082看看Tomcat是否启动成功。6) 访问对应的http://localhost:6060|6061|6062看看JMX exporter提供的metrics。备注:这里提供的simple-config.yml仅仅提供了JVM的信息,更复杂的配置请参考JMX exporter文档。第二步:启动Prometheus1) 在之前新建目录prom-jvm-demo,新建一个文件prom-jmx.yml,内容如下:crape_configs: - job_name: ‘java’ static_configs: - targets: - ‘<host-ip>:6060’ - ‘<host-ip>:6061’ - ‘<host-ip>:6062’# alertmanager的地址alerting: alertmanagers: - static_configs: - targets: - ‘<host-ip>:9093’# 读取告警触发条件规则rule_files: - ‘/prometheus-config/prom-alert-rules.yml'2) 新建文件prom-alert-rules.yml,该文件是告警触发规则:# severity按严重程度由高到低:red、orange、yello、bluegroups: - name: jvm-alerting rules: # down了超过30秒 - alert: instance-down expr: up == 0 for: 30s labels: severity: yellow annotations: summary: “Instance {{ $labels.instance }} down” description: “{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 30 seconds.” # down了超过1分钟 - alert: instance-down expr: up == 0 for: 1m labels: severity: orange annotations: summary: “Instance {{ $labels.instance }} down” description: “{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minutes.” # down了超过5分钟 - alert: instance-down expr: up == 0 for: 5m labels: severity: blue annotations: summary: “Instance {{ $labels.instance }} down” description: “{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.” # 堆空间使用超过50% - alert: heap-usage-too-much expr: jvm_memory_bytes_used{job=“java”, area=“heap”} / jvm_memory_bytes_max * 100 > 50 for: 1m labels: severity: yellow annotations: summary: “JVM Instance {{ $labels.instance }} memory usage > 50%” description: “{{ $labels.instance }} of job {{ $labels.job }} has been in status [heap usage > 50%] for more than 1 minutes. current usage ({{ $value }}%)” # 堆空间使用超过80% - alert: heap-usage-too-much expr: jvm_memory_bytes_used{job=“java”, area=“heap”} / jvm_memory_bytes_max * 100 > 80 for: 1m labels: severity: orange annotations: summary: “JVM Instance {{ $labels.instance }} memory usage > 80%” description: “{{ $labels.instance }} of job {{ $labels.job }} has been in status [heap usage > 80%] for more than 1 minutes. current usage ({{ $value }}%)” # 堆空间使用超过90% - alert: heap-usage-too-much expr: jvm_memory_bytes_used{job=“java”, area=“heap”} / jvm_memory_bytes_max * 100 > 90 for: 1m labels: severity: red annotations: summary: “JVM Instance {{ $labels.instance }} memory usage > 90%” description: “{{ $labels.instance }} of job {{ $labels.job }} has been in status [heap usage > 90%] for more than 1 minutes. current usage ({{ $value }}%)” # 在5分钟里,Old GC花费时间超过30% - alert: old-gc-time-too-much expr: increase(jvm_gc_collection_seconds_sum{gc=“PS MarkSweep”}[5m]) > 5 * 60 * 0.3 for: 5m labels: severity: yellow annotations: summary: “JVM Instance {{ $labels.instance }} Old GC time > 30% running time” description: “{{ $labels.instance }} of job {{ $labels.job }} has been in status [Old GC time > 30% running time] for more than 5 minutes. current seconds ({{ $value }}%)” # 在5分钟里,Old GC花费时间超过50% - alert: old-gc-time-too-much expr: increase(jvm_gc_collection_seconds_sum{gc=“PS MarkSweep”}[5m]) > 5 * 60 * 0.5 for: 5m labels: severity: orange annotations: summary: “JVM Instance {{ $labels.instance }} Old GC time > 50% running time” description: “{{ $labels.instance }} of job {{ $labels.job }} has been in status [Old GC time > 50% running time] for more than 5 minutes. current seconds ({{ $value }}%)” # 在5分钟里,Old GC花费时间超过80% - alert: old-gc-time-too-much expr: increase(jvm_gc_collection_seconds_sum{gc=“PS MarkSweep”}[5m]) > 5 * 60 * 0.8 for: 5m labels: severity: red annotations: summary: “JVM Instance {{ $labels.instance }} Old GC time > 80% running time” description: “{{ $labels.instance }} of job {{ $labels.job }} has been in status [Old GC time > 80% running time] for more than 5 minutes. current seconds ({{ $value }}%)“3) 启动Prometheus:docker run -d \ –name=prometheus \ -p 9090:9090 \ -v <path-to-prom-jvm-demo>:/prometheus-config \ prom/prometheus –config.file=/prometheus-config/prom-jmx.yml4) 访问http://localhost:9090/alerts应该能看到之前配置的告警规则:如果没有看到三个instance,那么等一会儿再试。第三步:配置Grafana参考使用Prometheus+Grafana监控JVM第四步:启动Alertmanager1) 新建一个文件alertmanager-config.yml:global: smtp_smarthost: ‘<smtp.host:ip>’ smtp_from: ‘<from>’ smtp_auth_username: ‘<username>’ smtp_auth_password: ‘<password>’# The directory from which notification templates are read.templates: - ‘/alertmanager-config/*.tmpl’# The root route on which each incoming alert enters.route: # The labels by which incoming alerts are grouped together. For example, # multiple alerts coming in for cluster=A and alertname=LatencyHigh would # be batched into a single group. group_by: [‘alertname’, ‘instance’] # When a new group of alerts is created by an incoming alert, wait at # least ‘group_wait’ to send the initial notification. # This way ensures that you get multiple alerts for the same group that start # firing shortly after another are batched together on the first # notification. group_wait: 30s # When the first notification was sent, wait ‘group_interval’ to send a batch # of new alerts that started firing for that group. group_interval: 5m # If an alert has successfully been sent, wait ‘repeat_interval’ to # resend them. repeat_interval: 3h # A default receiver receiver: “user-a”# Inhibition rules allow to mute a set of alerts given that another alert is# firing.# We use this to mute any warning-level notifications if the same alert is # already critical.inhibit_rules:- source_match: severity: ‘red’ target_match_re: severity: ^(blue|yellow|orange)$ # Apply inhibition if the alertname and instance is the same. equal: [‘alertname’, ‘instance’]- source_match: severity: ‘orange’ target_match_re: severity: ^(blue|yellow)$ # Apply inhibition if the alertname and instance is the same. equal: [‘alertname’, ‘instance’]- source_match: severity: ‘yellow’ target_match_re: severity: ^(blue)$ # Apply inhibition if the alertname and instance is the same. equal: [‘alertname’, ‘instance’]receivers:- name: ‘user-a’ email_configs: - to: ‘<user-a@domain.com>‘修改里面关于smtp_*的部分和最下面user-a的邮箱地址。备注:因为国内邮箱几乎都不支持TLS,而Alertmanager目前又不支持SSL,因此请使用Gmail或其他支持TLS的邮箱来发送告警邮件,见这个issue2) 新建文件alert-template.tmpl,这个是邮件内容模板:{{ define “email.default.html” }}<h2>Summary</h2> <p>{{ .CommonAnnotations.summary }}</p><h2>Description</h2><p>{{ .CommonAnnotations.description }}</p>{{ end}}3) 运行下列命令启动:docker run -d \ –name=alertmanager \ -v <path-to-prom-jvm-demo>:/alertmanager-config \ -p 9093:9093 \ prom/alertmanager –config.file=/alertmanager-config/alertmanager-config.yml4) 访问http://localhost:9093,看看有没有收到Prometheus发送过来的告警(如果没有看到稍等一下):第五步:等待邮件等待一会儿(最多5分钟)看看是否收到邮件。如果没有收到,检查配置是否正确,或者docker logs alertmanager看看alertmanager的日志,一般来说都是邮箱配置错误导致。 ...

October 26, 2018 · 5 min · jiezi

使用Prometheus+Grafana监控JVM

原文地址摘要用到的工具:Docker,本文大量使用了Docker来启动各个应用。Prometheus,负责抓取/存储指标信息,并提供查询功能。Grafana,负责数据可视化。JMX exporter,提供JMX中和JVM相关的信息。Tomcat,用来模拟一个Java应用。先讲一下大致步骤:利用JMX exporter,在Java进程内启动一个小型的Http server配置Prometheus抓取那个Http server提供的数据。配置Grafana连接Prometheus,配置Dashboard。第一步:启动几个Java应用1) 新建一个目录,名字叫做prom-jvm-demo。2) 下载JMX exporter到这个目录3) 新建一个文件simple-config.yml内容如下:—blacklistObjectNames: [":"]4) 运行以下命令启动3个Tomcat,记得把<path-to-prom-jvm-demo>替换成正确的路径:docker run -d \ –name tomcat-1 \ -v <path-to-prom-jvm-demo>:/jmx-exporter \ -e CATALINA_OPTS="-Xms64m -Xmx128m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.3.1.jar=6060:/jmx-exporter/simple-config.yml" \ -p 6060:6060 \ -p 8080:8080 \ tomcat:8.5-alpinedocker run -d \ –name tomcat-2 \ -v <path-to-prom-jvm-demo>:/jmx-exporter \ -e CATALINA_OPTS="-Xms64m -Xmx128m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.3.1.jar=6060:/jmx-exporter/simple-config.yml" \ -p 6061:6060 \ -p 8081:8080 \ tomcat:8.5-alpinedocker run -d \ –name tomcat-3 \ -v <path-to-prom-jvm-demo>:/jmx-exporter \ -e CATALINA_OPTS="-Xms64m -Xmx128m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.3.1.jar=6060:/jmx-exporter/simple-config.yml" \ -p 6062:6060 \ -p 8082:8080 \ tomcat:8.5-alpine5) 访问http://localhost:8080|8081|8082看看Tomcat是否启动成功。6) 访问对应的http://localhost:6060|6061|6062看看JMX exporter提供的metrics。备注:这里提供的simple-config.yml仅仅提供了JVM的信息,更复杂的配置请参考JMX exporter文档。第二步:启动Prometheus1) 在之前新建目录prom-jvm-demo,新建一个文件prom-jmx.yml,内容如下:crape_configs: - job_name: ‘java’ static_configs: - targets: - ‘<host-ip>:6060’ - ‘<host-ip>:6061’ - ‘<host-ip>:6062'2) 启动Prometheus:docker run -d \ –name=prometheus \ -p 9090:9090 \ -v <path-to-prom-jvm-demo>:/prometheus-config \ prom/prometheus –config.file=/prometheus-config/prom-jmx.yml3) 访问http://localhost:9090看看Prometheus是否启动成功,在输入框里输入jvm_info然后执行,应该可以看到如下图的结果:如果没有看到三个instance,那么等一会儿再试。第三步:配置Grafana1) 启动Grafana:docker run -d –name=grafana -p 3000:3000 grafana/grafana2) 访问http://localhost:3000,使用admin/admin登录。3) 添加Prometheus数据源,如下图所示到添加数据源页面:4) 配置数据源信息:Name:随便取Type:PrometheusURL:http://<host-ip>:9090其余不要设置,点击Save & Test,应该会返回成功结果5) 导入Dashboard。我们不需要重头自己做Dashboard,用现成的就行,按下图所示进入导入页面6) 使用我制作的JVM Dashboard,页面右侧出现的ID号是8563,记住这个号,填在如下图所示的位置:7) 然后鼠标点击别处稍等一下,出现下图,选择一下数据源就可以了8) 最后打开刚刚导入的Dashboard,如下图: ...

October 25, 2018 · 1 min · jiezi

利用VisualVm和JMX远程监控K8S里的Java进程

原文地址在利用VisualVm和JMX远程监控Java进程和VisualVm利用SSL连接JMX的方法里介绍了如何使用VisualVm+JMX监控远程Java进程的方法。那么如何监控一个运行在K8S集群中的Java进程呢?其实大致方法也是类似的。非SSL JMX连接如果采用非SSL JMX连接,那么你只需要这么几步就可以让你本地的VisualVm连接到K8S集群里的Java进程了。Step1 修改Deployment.yaml,添加以下System Properties-Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.port=1100-Dcom.sun.management.jmxremote.rmi.port=1100-Djava.rmi.server.hostname=localhost注意,-Djava.rmi.server.hostname一定要设置成localhostStep2 修改Deployment.yaml,添加Container Portcontainers:- name: … image: … ports: - containerPort: 1100 name: tcp-jmxStep3 部署DeploymentStep4 利用kubectl转发端口kubectl -n <namespace> port-forward <pod-name> 1100Step5 启动VisualVm,创建JMX连接localhost:1100SSL JMX连接启用SSL JMX连接,那么需要增加三个步骤,步骤就稍微复杂一些,假设你已经根据VisualVm利用SSL连接JMX的方法创建好了java-app和visualvm的keystore和truststore。Step1 创建一个Secret包含java-app.keystore和java-app.truststorekubectl -n <namespace> create secret generic jmx-ssl \ –from-file=java-app.keystore \ –from-file=java-app.truststoreStep2 修改Deployment.yaml,把Secret挂载到容器内的/jmx-ssl目录下 containers: - name: … image: … volumeMounts: - name: jmx-ssl-vol mountPath: /jmx-ssl volumes: - name: jmx-ssl-vol secret: secretName: jmx-sslStep3 修改Deployment.yaml,添加以下System Properties-Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.port=1100-Dcom.sun.management.jmxremote.rmi.port=1100-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=true-Dcom.sun.management.jmxremote.registry.ssl=true-Dcom.sun.management.jmxremote.ssl.need.client.auth=true-Djavax.net.ssl.keyStore=/jmx-ssl/java-app.keystore-Djavax.net.ssl.keyStorePassword=<keystore password>-Djavax.net.ssl.trustStore=/jmx-ssl/java-app.truststore-Djavax.net.ssl.trustStorePassword=<truststore password>-Djava.rmi.server.hostname=localhost注意,-Djava.rmi.server.hostname一定要设置成localhostStep4 修改Deployment.yaml,添加Container Portcontainers:- name: … image: … ports: - containerPort: 1100 name: tcp-jmx …Step5 部署DeploymentStep6 利用kubectl转发端口kubectl -n <namespace> port-forward <pod-name> 1100Step7 启动VisualVm,创建JMX连接localhost:1100jvisualvm -J-Djavax.net.ssl.keyStore=<path to visualvm.keystore> \ -J-Djavax.net.ssl.keyStorePassword=<visualvm.keystore的密码> \ -J-Djavax.net.ssl.trustStore=<path to visualvm.truststore> \ -J-Djavax.net.ssl.trustStorePassword=<visualvm.truststore的密码>K8S样例配置文件相关K8S样例配置文件在这里(用tomcat做的例子)。 ...

October 15, 2018 · 1 min · jiezi

VisualVm利用SSL连接JMX的方法

原文地址在前一篇文章里提到在生产环境下应该使用SSL来创建JMX连接,本文就来讲一下具体怎么做。前导知识先了解一下Java客户端程序在创建SSL连接的一些相关的事情:Java client程序在做SSL连接的时候,会拉取server的证书,利用truststore去验证这个证书,如果不存在 or 证书过期 or 不是由可信CA签发,就意味着服务端不被信任,就不能连接。如果在程序启动时没有特别指定使用哪个truststore(通过System Property javax.net.ssl.trustStore 指定),那么就会使用$JAVA_HOME/jre/lib/security/cacerts。如果指定了,就会使用指定的truststore + cacerts来验证。cacerts存放了JDK信任的CA证书(含有public key),它里面预先已经存放了已知的权威CA证书。你可以通过keytool -list -keystore - $JAVA_HOME/jre/lib/security/cacerts看到(让你输密码的时候直接回车就行了)以上过程被称为server authentication,也就是说client验证server是否可信,server authentication是最常见的,https就是这种模式。不过在用SSL连接JMX的时候,还要做client authentication,即server验证client是否可信。原理和上面提到的一样,只不过变成server用自己的truststore里验证client的证书是否可信。第一步:制作keystore和truststore上面提到的证书主要保存了一个public key,SSL是一个非对称加密协议,因此还有一个对应的private key,在java里private key和private key存放在keystore里。下面我们来制作visualvm(client)和java app(server)的keystore和truststore。先讲大致流程,然后再给出命令:生成visualvm的keystore,导出cert,把cert导入到java-app的truststore里生成java-app的keystore,导出cert,把cert导入到visualvm的truststore里具体命令:生成visualvm的keystore keytool -genkeypair \ -alias visualvm \ -keyalg RSA \ -validity 365 \ -storetype pkcs12 \ -keystore visualvm.keystore \ -storepass <visualvm keystore的密码> \ -keypass <同visualvm keystore的密码> \ -dname “CN=<姓名>, OU=<组织下属单位>, O=<组织名称>, L=<城市>, S=<省份>, C=<国家2字母>“导出visualvm的certkeytool -exportcert \ -alias visualvm \ -storetype pkcs12 \ -keystore visualvm.keystore \ -file visualvm.cer \ -storepass <visualvm keystore的密码>把visualvm的cert导入到java-app的truststore里,实际上就是生成了一个truststorekeytool -importcert \ -alias visualvm \ -file visualvm.cer \ -keystore java-app.truststore \ -storepass <java-app truststore的密码> \ -noprompt生成java-app的keystore keytool -genkeypair \ -alias java-app \ -keyalg RSA \ -validity 365 \ -storetype pkcs12 \ -keystore java-app.keystore \ -storepass <java-app keystore的密码> \ -keypass <同java-app keystore的密码> \ -dname “CN=<姓名>, OU=<组织下属单位>, O=<组织名称>, L=<城市>, S=<省份>, C=<国家2字母>“导出java-app的certkeytool -exportcert \ -alias java-app \ -storetype pkcs12 \ -keystore java-app.keystore \ -file java-app.cer \ -storepass <java-app keystore的密码>把java-app的cert导入到visualvm的truststore里keytool -importcert -alias java-app \ -file java-app.cer \ -keystore visualvm.truststore \ -storepass <visualvm truststore的密码> \ -noprompt所以最终得到的文件是这么几个:visualvm.keystore,包含visualvm的public key和private keyvisualvm.truststore,包含java-app certjava-app.keystore,包含java-app的public key和private keyjava-app.truststore,包含visualvm cert第二步:启动Tomcat我们还是用Tomcat做实验,给CATALINA_OPTS添加几个参数像下面这样,因为参数比较多,所以我们在$TOMCAT/bin下添加一个setenv.sh的文件(记得加上可执行权限):CATALINA_OPTS="-Dcom.sun.management.jmxremote"CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=1100"CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=true"CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.hostname=<host or ip>“CATALINA_OPTS="$CATALINA_OPTS -Djavax.net.ssl.keyStore=<path to java-app.keystore>“CATALINA_OPTS="$CATALINA_OPTS -Djavax.net.ssl.keyStorePassword=<java-app.keystore的密码>“CATALINA_OPTS="$CATALINA_OPTS -Djavax.net.ssl.trustStore=<path to java-app.truststore>“CATALINA_OPTS="$CATALINA_OPTS -Djavax.net.ssl.trustStorePassword=<java-app.truststore的密码>“然后$TOMCAT/bin/startup.sh第三步:启动visualvmjvisualvm -J-Djavax.net.ssl.keyStore=<path to visualvm.keystore> \ -J-Djavax.net.ssl.keyStorePassword=<visualvm.keystore的密码> \ -J-Djavax.net.ssl.trustStore=<path to visualvm.truststore> \ -J-Djavax.net.ssl.trustStorePassword=<visualvm.truststore的密码>你可以不加参数启动jvisualvm,看看下一步创建JMX连接是否成功,如果配置正确应该是不会成功的。第四步:创建JMX连接加了上述参数启动jvisualvm后,和利用VisualVm和JMX远程监控Java进程里提到的步骤一样创建JMX连接,只不过在创建JMX连接的时候不要勾选【不要求SSL连接】(不过经实测,勾不勾选都能连接成功的)。参考资料Monitoring and Management Using JMX Technology - Using SSLCustomizing the Default Keystores and Truststores, Store Types, and Store PasswordsCustomizing JSSE,这个表格列出了一些SSL相关的System PropertiesCreating a Keystore to Use with JSSEkeytoolMonitor Java with JMXJava Secure Socket Extension (JSSE) Reference Guide,这是Java对于SSL支持的最全的参考文档我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/dev… ...

October 13, 2018 · 2 min · jiezi

利用VisualVm和JMX远程监控Java进程

原文地址在前一篇文章里我们发现通过jstatd + VisualVm的方式,不能获得Java进程的CPU、线程、MBean信息,这时JMX就要登场了。自Java 6开始,Java程序启动时都会在JVM内部启动一个JMX agent,JMX agent会启动一个MBean server组件,把MBeans(Java平台标准的MBean + 你自己创建的MBean)注册到它里面,然后暴露给JMX client管理。简单来说就是每个Java程序都可以通过JMX来被JMX client管理,而且这一切都是自动发生的。而VisualVm就是一个JMX Client。VisualVm能够自动发现本机的Java进程,如果要监控远程主机上的Java进程则需要显式地配置JMX连接,下面讲配置方法:第一步:已经用jstatd连接了远程主机已经根据利用VisualVm远程监控Java进程里的方法在VisualVm里添加了远程主机。PS. 在实际使用过程中这个似乎不是必须的,但是如果不做,有些信息就会获取不到,因此还是做一下吧。第二步:与启动相关的System Properties要给远程主机上的监控的Java进程在启动时必须带上几个JMX相关的System Properties(常用的几个):com.sun.management.jmxremote.port, 指定暴露的JMX端口。com.sun.management.jmxremote.ssl, 指定是否使用SSL,在开发环境下可以是false,但是在生产环境下强烈建议为true。com.sun.management.jmxremote.authenticate, 指定是否需要密码才能够创建JMX连接。为了演示目的,我们用Tomcat来测试,不开启ssl和authenticate,把JMX端口设置为1100,执行下列命令启动Tomcat:CATALINA_OPTS=’-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=1100 -Djava.rmi.server.hostname=k8s-oracle’ bin/startup.sh注意上面有一个-Djava.rmi.server.hostname=k8s-oracle参数,JMX agent本质上也是一个RMI server,因此需要指定这个参数,否则就会像利用VisualVm远程监控Java进程里提到的一样,VisualVm无法连接到该Java进程。PS. 使用SSL方式保护JMX连接的方法会另写文章说明。第三步:创建JMX连接在远程主机上右键,选择添加JMX连接(在下图里出现了之前启动的Tomcat进程):根据Java进程启动时设置的JMX System Properties配置JMX连接:成功后你会发现多了一个进程,小图标上有JMX字样:双击这个进程,你就能看到CPU、线程、还有MBeans了。参考资料VisualVm - Connecting to JMX Agents ExplicitlyUsing JMX AgentsMBeans Tab

October 11, 2018 · 1 min · jiezi