监控
springboot actuator
查看端点(endpoints)
- 在项目里导入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 启动项目,访问
/actuator
,即可看到暴露的端点以及对应的url
{
"_links":{
"self":{
"href":"http://localhost:8081/actuator",
"templated":false
},
"health":{
"href":"http://localhost:8081/actuator/health",
"templated":false
},
"health-path":{
"href":"http://localhost:8081/actuator/health/{*path}",
"templated":true
}
}
}
- 如果想要暴露其他的endpoints,可以在配置文件配置
management:
endpoints:
web:
exposure:
#直接全部暴露,如果想部分的话多个之间用逗号隔开
include: "*"
重要端点(endpoints)
/health
-
url:
/actuator/health
-
/health端点会聚合程序的健康指标,来检查程序的健康情况,如redis,rabbitmq、db等组件,当你的项目有依赖对应组件的时候,这些健康指示器就会被自动装配,继而采集对应的信息
-
默认是不公开建康信息的细节,只能看到程序有没有上线,如果想看到健康信息的详细内容,需要设置配置
management:
endpoint:
health:
##always:表示对所有用户暴露详细信息
##never(默认):不展示详细信息,只显示up或down的状态
#when-authorized:详细信息将会展示给通过谁的用户,授权的角色可以通过management.endpoint.health.roles配置
show-details: always
/metrics
-
url:
/actuator/metrics
-
/metrics端点用来返回当前应用的各类重要试题指标,比如:内存信息、线程信息、垃圾回收信息、数据库连接池等
-
访问上面的url,只是给出指标的列表,访问具体哪个指标信息,可以这样:
/actuator/metrics/{指标名}
/loggers
-
url:
/actuator/loggers
-
/logger端点暴露了我们程序内部配置的所有logger信息
- 查看某一个组件服务或某一个应用的日志级别,并对其进行实时的变量
- looogers endpoint 同时提供了在应用运行时改变日志级别的能力,可以发一个post请求即可
/actuator/loggers/{logName}
,json入参{"configuredLevel":"DEBUG"}
,如果想弄回默认级别,这个入参就传个空字符串就行
/beans
-
url:/actuator/beans
-
返回spring窗口中所有bean的别名、类型、是否单例、依赖等信息
/heapdump
- url:/actuator/heapdump
- 访问这个会返回一个jvm的堆文件heapdump,可以用jdk自带的jvm监控工具(java的bin目录下的jvisualvm)查看内存快照
/threaddump
- url:/actuator/threaddump
- 查看线程情况,展示了线程名、线程ID、线程状态、是否等待锁资源、线程堆栈等信息
springboot集成prometheus、grafana、alertmanager
简单介绍
- prometheus:系统和服务监控软件和时间序列数据库
- grafana:数据看板工具
- alertmanager:prometheus官方提供的告警工具,可以连接钉钉、企业微信、邮箱等
安装
略,都是下载安装包,解压,用就改一下配置文件,启动
也可以用docker,看个人喜欢
集成prometheus
- 引入依赖
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.6.4</version>
</dependency>
添加依赖后,springboot将会自动配置PrometheusMeterRegistry和CollectorRegistry来以prometheus可以抓取的格式收集和导出指标数据
-
访问
/actuator/prometheus
,可以看到按照Metrics格式组织起来的程序监控指标数据metric name>(<label name>=<label value>,...)
-
application.yml
server:
port: 8081
spring:
application:
name: prometheus-demo
#actuator暴露endpoint
management:
endpoints:
web:
exposure:
include: "*"
metrics:
tags:
application: ${spring.application.name}
- 修改prometheus.yml
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
#上面部分是prometheus自己的,下面才是我们的配置
#job_name写应用名
- job_name: 'prometheus-demo'
#metrics_path写我们应用能拿到监控数据的地址
metrics_path: '/actuator/prometheus'
#应用的ip端口
static_configs:
- targets: ['192.168.31.246:8081']
-
启动prometheus:
./prometheus --config.file=prometheus.yml
,启动后访问localhost:9090
进入,ip自行替换 -
在prometheus的target页面,就可以看到我们自己添加进去的应用了
集成grafana
-
启动
./bin/grafana-server web
,启动后访问```localhost:3000进入,ip自行替换 -
进入页面之后,初始账号密码admin/admin,后面自己重新设置初始密码
-
进入grafana之后,先进入configuration,点击add data source,之后将我们的prometheus的配置填进去,生成一个数据源
-
之后再找到一个import按钮,它应该在一个+的菜单栏里,这里可以添加一个url,或者一个json来导入一个视图模板,可以去grafana官网找,这里放一个推荐的
https://grafana.com/dashboards/4701
,用这个模板还需要在应用中多配置一个bean,这个是人家在文档里面说的,不信可以访问一下上面这个url去看一看
@Bean
MeterRegistryCustomizer<MeterRegistry> configurer(
@Value("${spring.application.name}") String applicationName) {
return (registry) -> registry.config().commonTags("application", applicationName);
}
- 导入完之后就可以看到我们的应用的信息了
集成alertmanager
先占个坑,以后看看,告警先用grafana的,下面整活
自定义metrics
监控方法执行次数、耗时
代码部分
使用TimedAspect
类,能轻松获取我们的方法的执行次数和总耗时,通过一点简单的计算也可以得到平均耗时,下面做一个简单的demo
- 引入依赖
- io.micrometer里面有把我们的数据转换成prometheus能够识别的metrics格式的数据
- aspectjweaver是因为TimedAspect中需要用到aop,所以需要导入,不导入会报错
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.6.4</version>
</dependency>
<!--aop的包,用一个timeAspects的包要用到-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>
- 注册
TimedAspect
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
- 写个Service,重点:@Timed注解
- 这里简单用一下定时任务
@Scheduled(cron = "*/5 * * * * ?")
- 记得在springboot启用类上加上
@EnableScheduling
- 不用定时任务就自己写个controller去调也好,不过不是很推荐,后面要监控实时的数据,写成定时任务好一点
- 这里简单用一下定时任务
@Service
public class TimeActuatorService {
@Scheduled(cron = "*/5 * * * * ?")
//加上此注解后,能够收集它的方法执行次数,方法执行总耗时
//有了上述两点信息,也可以得到平均耗时
@Timed(description = "service.doOperation")
public String doOperation() {
int num = new Random().nextInt(100);
try {
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
return String.valueOf(num);
}
}
- 启动应用,访问地址
/actuator/prometheus
,能在监控到的数据里看到如下信息:- doOperation方法的执行次数
- doOperation方法的总耗时
- doOperation单次执行最长耗时
使用grafana展示
-
进入页面,选择create dashboard,
不会有人找不到吧 -
点击add new panel,之后如下图操作
- 之后点右上角的保存,这里没截图到,保存之后就可以在我们的dashboard上看到我们自定义的监控内容图表
计数监控(计算奇偶个数)
除了使用现成的TimedAspect
当然micrometer还支持我们自定义其他的metrics,像counter、guage等,这里举一个简单的counter
代码部分
这里对上面的Service做了亿点点的修改:
- 添加了两个counter
- counter可以使用MeterRegistry对象来生成,也可以通过一个构造者来生成
- oddCounter和evenCounter分别来记录奇偶数
@Service
public class TimeActuatorService {
@Autowired
private MeterRegistry meterRegistry;
private Counter oddCounter;
private Counter evenCounter;
@PostConstruct
public void init() {
//奇数计数器,tags为metric name和metric value
oddCounter = meterRegistry.counter("odd counter", "name", "odd counter");
oddCounter.increment();
//偶数计数器,tags为metric name和metric value,也可以用builder来构建一个counter
evenCounter = meterRegistry.counter("even counter", "name", "even counter");
evenCounter.increment();
//evenCounter = Counter.builder("even counter")
// .tag("name", "even counter")
// .register(meterRegistry);
}
@Scheduled(cron = "*/5 * * * * ?")
//加上此注解后,能够收集它的方法执行次数,方法执行总耗时
//有了上述两点信息,也可以得到平均耗时
@Timed(description = "service.doOperation")
public String doOperation() {
int num = new Random().nextInt(100);
try {
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (num % 2 == 0) {
evenCounter.increment();
} else {
oddCounter.increment();
}
return String.valueOf(num);
}
}
使用grafana展示
在上面原有的dashboard上面继续add panel就好,PromQL就不专门展示了
grafana警报
这里选择用qq邮箱来做警报
配置grafana.ini
在grafana的conf目录下,有一个defaults.ini文件,一般不直接用它,拷贝一份出来,
#复制、编辑
cp defaults.ini customer.ini
vim customer.ini
#在下面需要改动的地方改一下,都标记好地方了
#修改SMTP部分内容
#################################### SMTP / Emailing #####################
[smtp]
#需要改
enabled = true
#需要改
host = smtp.qq.com:465
#需要改
user = xxx@qq.com
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
#需要改
password = xxxxxxx
cert_file =
key_file =
#需要改
skip_verify = true
#需要改
from_address = xxx@qq.com
#from_address = admin@grafana.localhost
#需要改
from_name = Grafana
ehlo_identity =
startTLS_policy =
[emails]
welcome_email_on_sign_up = false
templates_pattern = emails/*.html
重启grafana
#指定配置文件重启grafana,认好现在的目录哦
./bin/grafana-server -config=conf/customer.ini
添加channel
来到grafana页面,点击左侧菜单栏的alerting—notifaction channels—new channel,之后填写内容
-
name:channel的名字
-
type:Email(我选的是用qq邮箱)
-
Address:你要发送到的邮箱地址
配置好上面三项后,点击下面的test,测试一下能不能发送成功,成功后点击save
添加报警规则
进入一个dashboard,之后找一个panel,点击edit,进入后找到alert,设置好rule、condition等后保存,详细内容见下
-
Rule
- Name:这个pannel的名字,不用动
- Evaluate every:检测频率
- For:当触发了报警条件时,等过了For设置的时间后,再发送报警事件
-
Conditions
- WHEN:选择一个聚合函数
- OF:query的条件
- IS ABOVE:超过,也可选其他操作符
-
No Data & Error Handling
- if no data or all values are null:如果没有数据或值都为空
- if execution error or timeout:如果执行错误或超时
-
Send to:指定channel
-
Message:报警内容
触发rule就能收到报警邮件