1、新建SpringBoot项目
2、引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<!--<version>1.6.2</version>-->
</dependency>
3、更改application.properties
server.port=8088
spring.application.name=spg
#注意此处使用,访问的时候必须访问/actuator/prometheus,如不配置则访问/prometheus
management.endpoints.web.base-path=/actuator
management.endpoints.web.exposure.include=*
4、启动SpringBoot工程
启动服务,浏览器访问 http://127.0.0.1:8088/actuator/prometheus 就可以看到应用的 一系列不同类型 metrics 信息,
例如 http_server_requests_seconds summary、jvm_memory_used_bytes gauge、jvm_gc_memory_promoted_bytes_total counter 等等
5、安装启动Prometheus
5.1、编辑prometheus.yml
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'codelab-monitor'
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
#SpringBoot应用配置
- job_name: 'spg'
scrape_interval: 5s
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['172.24.83.202:8088']
5.2、容器方式启动Prometheus
docker run
-p 9090:9090
-v /Users/zhangxm/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
--name prometheus-9090 prom/prometheus
6、安装配置Grafana
6.1、安装启动
docker run -d --name=grafana-3000 -p 3000:3000 grafana/grafana
6.2、登录Grafana,增加Prometheus数据源
7、Micrometer 介绍
Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,
它提供了多种度量指标类型(Timers、Guauges、Counters等),
同时支持接入不同的监控系统,例如 Influxdb、Graphite、Prometheus 等。
我们可以通过 Micrometer 收集 Java 性能数据,配合 Prometheus 监控系统实时获取数据,并最终在 Grafana 上展示出来,从而很容易实现应用的监控。
Micrometer 中有两个最核心的概念,分别是计量器(Meter)和计量器注册表(MeterRegistry)。
计量器用来收集不同类型的性能指标信息,Micrometer 提供了如下几种不同类型的计量器:
计数器(Counter): 表示收集的数据是按照某个趋势(增加/减少)一直变化的,也是最常用的一种计量器,例如接口请求总数、请求错误总数、队列数量变化等。
计量仪(Gauge): 表示搜集的瞬时的数据,可以任意变化的,例如常用的 CPU Load、Mem 使用量、Network 使用量、实时在线人数统计等,
计时器(Timer): 用来记录事件的持续时间,这个用的比较少。
分布概要(Distribution summary): 用来记录事件的分布情况,表示一段时间范围内对数据进行采样,可以用于统计网络请求平均延迟、请求延迟占比等。
8、自定义监控指标并展示到 Grafana
上边是 spring-boot-actuator 集成了 Micrometer 来提供的默认监控项,覆盖 JVM 各个层间的监控,配合 Grafana Dashboard 模板基本可以满足我们日常对 Java 应用的监控。
当然,它也支持自定义监控指标,实现各个方面的监控,
例如统计访问某一个 API 接口的请求数,统计实时在线人数、统计实时接口响应时间等功能,而这些都可以通过使用上边的四种计量器来实现。
接下来,来演示下如何自定义监控指标并展示到 Grafana 上。
8.1、监控某些api的调用次数
我们继续在 spg工程上添加 DemoController.java,来实现分别统计访问 index 及 core 接口请求次数,代码如下:
@RestController
@RequestMapping("/counter")
public class DemoController {
@RequestMapping("/hello")
public String hello(){
return "hello spg";
}
@Autowired
MeterRegistry registry;
private Counter counter_core;
private Counter counter_index;
@PostConstruct
private void init(){
counter_core = registry.counter("app_requests_method_count", "method", "DemoController.core");
counter_index = registry.counter("app_requests_method_count", "method", "DemoController.index");
}
@RequestMapping(value = "/index")
public Object index(){
try{
counter_index.increment();
} catch (Exception e) {
return e;
}
return counter_index.count() + " index of spg.";
}
@RequestMapping(value = "/core")
public Object coreUrl(){
try{
counter_core.increment();
} catch (Exception e) {
return e;
}
return counter_core.count() + " core Url Monitor by Prometheus.";
}
}
这里是一个简单的 RestController 接口,使用了 Counter 计量器来统计访问 /counter/index 接口访问量。
因为访问数会持续的增加,所以这里使用 Counter 比较合适。
启动服务,我们来分别访问一下这两个接口,为了更好的配合下边演示,可以多访问几次。
接下来,我们可以到 Prometheus UI 界面上使用 PromSQL 查询自定义的监控信息了。
添加 Graph 并执行如下查询语句,查询结果如下:
app_requests_method_count_total{application="spg", method="DemoController.index"} 这里的
- app_requests_method_count_total 为上边代码中设置的 Counter 名称。
- application 为初始化 registry 时设置的通用标签,标注应用名称,这样做好处就是可以根据应用名称区分不同的应用。
- instance 为 <local_dir>/groups/applicationgroups/application.json 中配置的 instance 实例名称,用来区分应用实例。
- method 为上边代码中设置的 Counter 标签名称,可以用来区分不同的方法,这样就不用为每一个方法设置一个 Counter 了。
$ vim prommetheus.yml
......
- job_name: 'application'
scrape_interval: 5s
metrics_path: '/actuator/prometheus'
file_sd_configs:
- files: ['/usr/local/prometheus/groups/applicationgroups/*.json']
----------------------------------------------------------------------
这里依然采用 file_sd_configs 方式动态服务发现,新建 <local_dir>/groups/applicationgroups/application.json 文件如下:
$ vim groups/applicationgroups/application.json
[
{
"targets": [
"192.168.1.124:8088"
],
"labels": {
"instance": "spg",
"service": "spg-service"
}
}
]
这里 192.168.1.124:8088 就是上边本地启动的服务地址,也就是 Prometheus 要监控的服务地址,
同时添加一些与应用相关的标签,方便后期执行 PromSQL 查询语句区分。
最后重启 Prometheus 服务,查看 Prometheus UI 界面确认 Target 是否添加成功。
接下来,我们在 Grafana Dashboard 上添加一个新的 Panel 并添加 Query 查询,最后图形化展示出来。
首先添加一个 Panel 并命名为 自定义监控指标,然后点击 Add Query 增加一个新的 Query 查询,查询语句为上边的 PromSQL 语句,
不过这里为了更好的扩展性,我们可以将 application 及 instance 两个参数赋值为变量,而这些变量可以直接从 Prometheus 上传递过来,最终的查询语句为 app_requests_method_count_total{application="$application", instance="$instance", method="DemoController.index"},
最后修改 Title 为 实时访问量 /counter/index,保存一下,返回首页就可以看到刚添加的 Dashboard 了,是不是很直观。
Grafana之Variable
8.2、实时监控在线人数
@RestController
@RequestMapping("/v1")
public class IndexController {
@Autowired
MeterRegistry registry;
private Counter counter_core;
private Counter counter_index;
private AtomicInteger app_online_count;
@PostConstruct
private void init(){
counter_core = registry.counter("app_requests_method_count", "method", "IndexController.core");
counter_index = registry.counter("app_requests_method_count", "method", "IndexController.index");
app_online_count = registry.gauge("app_online_count", new AtomicInteger(0));
}
@RequestMapping(value = "/index")
public Object index(){
try{
counter_index.increment();
} catch (Exception e) {
return e;
}
return counter_index.count() + " index of springboot2-prometheus.";
}
@RequestMapping(value = "/core")
public Object coreUrl(){
try{
counter_core.increment();
} catch (Exception e) {
return e;
}
return counter_core.count() + " coreUrl Monitor by Prometheus.";
}
@RequestMapping(value = "/online")
public Object onlineCount(){
int people = 0;
try {
people = new Random().nextInt(2000);
app_online_count.set(people);
} catch (Exception e){
return e;
}
return "current online people: " + people;
}
}
重启服务,访问一下 /v1/online 接口,得到一个 2000 以内的随机数作为实时在线人数,