作一个系统,若是不作监控,是不完善的。java
若是为作一个快速系统,花力气去作监控,是不值得的。(监控系统不是你想作,想作就能作的。)linux
所以,咱们有必要具有一个可以快速创建监控体系的能力。即便你只是一个普通开发人员!(说不定明天就要叫你去领兵大操练呢)git
我的以为,作监控要有三个核心能力:github
1. 持续收集数据的能力; (时间序列数据库)
2. 监控结果可视化的能力;
3. 异常监控可报警的能力;
web
只要把这三点作到了,那么,这个监控基本就成功了。spring
既然本身不方便作监控系统,那就只要作好框架选型就能够了。数据库
因grafana的图表功能我的感受最强大,咱们就以 grafana 做为监控抓手点,建立本身的监控体系吧!json
监控体系大致实现思路:vim
1. 代码里写入埋点,或者其余系统经过探针之类的工具实现数据源;
2. 监控数据中心接收埋点数据等指标数据集;
3. 监控中心提供各类维度数据的计算汇总指标;
4. 自定义图表展示;
5. 根据结果设置报警;api
具体打开方法:
1. 写代码添加埋点;
2. 使用jmx采集工具采集数据;
3. 安装 prometheus, 配置好要调用的客户端;
4. 安装grafana;
5. 配置 prometheus 的数据源到 grafana 上;
6. 添加 grafana 监控图表;
7. 配置监控报警(通常你须要先配置linux邮件设置);
因此,看下具体怎么作吧,涉及到安装的部分就顺带过吧,毕竟其余地方,此类信息已经泛滥了!
1. 撸埋点代码(jmx)
.1 引入依赖包
<!-- jmx 埋点依赖 --> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-jmx</artifactId> <version>4.0.0</version> </dependency>
.2 封装指标上报工具类
import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.jmx.JmxReporter; import org.springframework.stereotype.Component; /** * 系统指标管理管理器实现类 * */ @Component public class SystemMetricsManagerImpl implements SystemMetricsManager { private static final MetricRegistry metricsContainer = new MetricRegistry(); static { JmxReporter jmxReporter = JmxReporter.forRegistry(metricsContainer).build(); jmxReporter.start(); } @Override public Meter registerAndGetMetricMeter(String meterName) { return metricsContainer.meter(meterName); } }
.3 在须要的地方添加埋点
// 在必要的地方,进行集中初始化 @Override public void afterPropertiesSet() throws Exception { consumeCounterHolder = new ConsumeCounterHolder(); consumeCounterHolder.initCounter(); } /** * 计数器容器实例 */ private ConsumeCounterHolder consumeCounterHolder; /** * 消费计数器容器,做为内部封装,如以为不爽,也能够抽离为独立对象隔离 */ class ConsumeCounterHolder { /** * 全部消费计数器 */ private Meter totalConsumeCounter; /** * 被抛弃的消费计数器 */ private Meter msgDiscardConsumeCounter; /** * 系统异常消费计数器 */ private Meter systemExceptionConsumeCounter; /** * 业务消费失败,回滚计数器 (通常不会存在值) */ private Meter processFailedConsumeCounter; /** * 中止消费计数器 */ private Meter listenerStoppedConsumeCounter; /** * 未知类型消费数计数器 */ private Meter unknownTypeConsumeCounter; /** * 初始化计数器 */ public void initCounter() { totalConsumeCounter = systemMetricsManager.registerAndGetMetricMeter( SystemMetricsConstants.MqConsumeCounter.TOTAL_COUNT_METRIC_NAME); msgDiscardConsumeCounter = systemMetricsManager.registerAndGetMetricMeter( SystemMetricsConstants.MqConsumeCounter.DISCARD_COUNT_METRIC_NAME); systemExceptionConsumeCounter = systemMetricsManager.registerAndGetMetricMeter( SystemMetricsConstants.MqConsumeCounter.SYSTEM_EXCEPTION_COUNT_METRIC_NAME); processFailedConsumeCounter = systemMetricsManager.registerAndGetMetricMeter( SystemMetricsConstants.MqConsumeCounter.PROCESS_FAILED_COUNT_METRIC_NAME); listenerStoppedConsumeCounter = systemMetricsManager.registerAndGetMetricMeter( SystemMetricsConstants.MqConsumeCounter.LISTENER_STOPPED_COUNT_METRIC_NAME); unknownTypeConsumeCounter = systemMetricsManager.registerAndGetMetricMeter( SystemMetricsConstants.MqConsumeCounter.UNKNOWN_TYPE_COUNT_METRIC_NAME); } /** * 增长消费计数 */ private void incTotalConsumeCounter() { totalConsumeCounter.mark(); } public void incMsgDiscardConsumeCounter() { msgDiscardConsumeCounter.mark(); } public void incSystemExceptionConsumeCounter() { systemExceptionConsumeCounter.mark(); } public void incProcessFailedConsumeCounter() { processFailedConsumeCounter.mark(); } public void incListenerStoppedConsumeCounter() { listenerStoppedConsumeCounter.mark(); } public void incUnknownTypeConsumeCounter() { unknownTypeConsumeCounter.mark(); } } /** * 业务方法中,调用埋点 * */ public void doSth() { // 添加各类埋点 consumeCounterHolder.incTotalConsumeCounter(); }
2. 使用jmx采集工具采集数据 (prometheus)
prometheus 做为流行的监控组件,能够很方便的接入 jmx 数据, 使用 jmxReporter 就能够了。
prometheus 项目地址: https://github.com/prometheus
jmxReporter 项目地址: https://github.com/prometheus/jmx_exporter
下载 jmxReporter agent: https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.11.0/jmx_prometheus_javaagent-0.11.0.jar
添加最简单的配置文件,采集全部jmx数据:
# vim config.yaml --- rules: - pattern: ".*"
最后,启动 jmxReporter, 提供采集依据:
java -javaagent:./jmx_prometheus_javaagent-0.11.0.jar=9088:config.yaml -jar yourJar.jar
注: jmxReporter 的原理实际上是开启一个http的socket端口,在外部请求进来以后,进行访问jmx数据进行返回。
3. 安装prometheus服务端,进行主动数据采集
.1 下载: https://prometheus.io/download/ , 找到对应版本下载便可;
.2 直接启动验证下: ./prometheus --config.file=prometheus.yml --web.enable-admin-api
.3 向 prometheus 中添加客户端机器地址,以便采集,咱们只使用一种简单的独立文件的配置方式:
# 1. 直接在文件末尾添加job便可 - job_name: 'jmx' file_sd_configs: - files: - conf.d/test.json # 2. 在 conf.d/test.json 中,添加相应的客户端机器ip [ { "targets": ["10.1.1.1:9088"] },{ "targets": ["10.1.1.2:9088"] },{ "targets": ["10.1.1.3:9088"] } ]
.4 重启 prometheus
kill -9 xxx ./prometheus --config.file=prometheus.yml --web.enable-admin-api
如此, prometheus 的数据库中就已经有 你的埋点数据了!
4. 安装 grafana
.1 下载地址: https://grafana.com/get
.2 能够直接使用镜像源安装,也可使用源码包自行编译;
.3 启动 grafana 服务: service grafana-server start
.4 你就能够打开 grafana 后台进行查看了(默认帐号密码是 admin/admin);
5. 新增 prometheus 做为 grafana 的数据源
grafana 支持不少数据源的接入,可是 prometheus 是比较简单的一种;
在设置 -> DataSources 中,添加 prometheus 的数据,按要求填写便可,通常只须要填写一个 prometheus 的请求地址就能够了。
6. 添加 grafana 监控图表;
直接点击 + 号,添加一个大盘;
而后就是各类页面拖拉拽!
拿几个须要注意的指标统计说明下:
# case1. 代码中的埋点为一个递增的值,我想知道每段时间的增加趋势是怎么样的?如: 1分钟 increase(metrics_test_mq_consume_total_Count[1m]) # case2. 在集群环境中,以上统计将是全部机器的总和,我想查看单个机器的增加趋势? increase(metrics_test_mq_consume_total_Count{instance=~"$instance_cust"}[1m]) # 其中 instance_cust 是定义在监控大盘上的自定义变量,其做用是 当前监控的实例的标识, 稍后咱们看下实例 # case3. 我想知道下当前机器的cpu负载 avg_over_time(java_lang_OperatingSystem_SystemCpuLoad{instance=~"$instance_cust"}[1m]) * 100 # case4. 我想查看当前机器的物理内存状况 java_lang_OperatingSystem_FreePhysicalMemorySize{instance=~"$instance_cust"} java_lang_OperatingSystem_TotalPhysicalMemorySize{instance=~"$instance_cust"} # case5. 我想查看jvm的内存状况 java_lang_Memory_HeapMemoryUsage_max{instance=~"$instance_cust"} java_lang_Memory_HeapMemoryUsage_used{instance=~"$instance_cust"} # 附: 添加大盘 通用变量 label_values(up{job='jmx'}, instance) 将会查询符合过滤条件的标签
附: 添加大盘 通用变量
label_values(up{job='jmx'}, instance) 将会查询符合过滤条件的标签
7. 配置监控报警(通常你须要先配置linux邮件设置);
以上都配置好以后,还能够进行报警配置。
alerting -> Notification Channels 中,添加告警通知通道。
而后,在原来的大盘中选择一个指标进行报警设置;而后就能够接收告警了。
固然,这里选择邮件,须要linux系统直接使用 mail 进行发送邮件才行。
如此,一个完整的监控链完成!
老话: 愿你戎马半生,归来还是少年。