本篇博客简单地聊一下如何使用spring boot actuator来对web服务进行监控,并重点聊一下接口的监控。spring boot actuator 1.x 版本和2.x版本的差别比较大,本文只讨论2.x。我目前使用的版本是2.0.5.RELEASE
。
spring boot actuator可以暴露一些用于监控的endpoint,使外部的监控程序来采集web服务当前的一些指标状态,还可以进行一些必要的交互。
spring boot项目集成actuator非常容易,只需要添加一个maven依赖就好了
org.springframework.boot
spring-boot-starter-actuator
依赖的version由parent来指定。
当项目启动时,访问’/actuator’地址,如果看到类似下面的内容,说明actuator已经生效了。
{
"_links": {
"self": {
"href": "http://localhost:8000/actuator",
"templated": false
},
"health": {
"href": "http://localhost:8000/actuator/health",
"templated": false
},
"info": {
"href": "http://localhost:8000/actuator/info",
"templated": false
}
}
}
从上面的输出可以看出,actuator只暴露了这么三个简单的endpoint,并且,只有/health
接口的内容还有点用,可以看出spring boot服务是否健康,或者是否活着。当然,actuator绝对不止这么点功能,只是出于安全考虑,其余的endpoint默认被禁用了。如果使用spring security的话,加入一些配置,就可以使对应的角色看到全部的内容。
为了简单起见,我们来开启所有接口。只需要在application.properties文件中加入一行配置即可
management.endpoints.web.exposure.include=*
修改后重启一下spring boot服务并刷新一下/actuator
页面,就会多出很多endpoint。关于每一个endpoint的解释,可以参考下面的文档
https://docs.spring.io/spring-boot/docs/2.0.6.RELEASE/reference/htmlsingle/#production-ready-endpoints-exposing-endpoints
访问/actuator/metrics
接口中,会返回actuator提供的所有metric的name
{
"names": [
"jvm.memory.max",
"process.files.max",
"jvm.gc.memory.promoted",
"tomcat.cache.hit",
"system.load.average.1m",
"tomcat.cache.access",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.gc.pause",
"jvm.memory.committed",
"http.server.requests",
"system.cpu.count",
"logback.events",
......
]
}
在/actuator/metrics
接口后面直接加上metric的name,则可以访问该metric的信息。我比较关心的是http.server.requests
这个metric,因为利用它可以完成对接口的监控
访问/actuator/metrics/http.server.requests
接口,可以看到类似下面的内容
{
"name": "http.server.requests",
"description": null,
"baseUnit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 5
},
{
"statistic": "TOTAL_TIME",
"value": 0.159962364
},
{
"statistic": "MAX",
"value": 0
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"None"
]
},
{
"tag": "method",
"values": [
"GET"
]
},
{
"tag": "uri",
"values": [
"/actuator",
"/actuator/metrics",
"/**/favicon.ico"
]
},
{
"tag": "status",
"values": [
"200"
]
}
]
}
在measurements
下面可以看到所有接口一共被访问了多少次,返回所有结果一共耗时了多久,返回最慢的接口耗时了多久等。单单是这些信息,并不觉得多么重要。但后面还有一个属性是availableTags
,它给出了所有可用的tag key和tag value,根据这些可以进一步筛选你想要监控的内容,来看如何根据tag进一步获取我们想要的监控信息。
可以用下面的语法来对tag进行筛选
/actuator/metrics/http.server.requests?tag=uri:/actuator/metrics
上面的地址可以只关注uri=/actuator/metrics的指标,可以看到该接口一共被访问了多少次,最慢的情况下耗时了多久等。
还可以同时根据多个tag来进行筛选,中间用,
隔开就行了。假设我只想关注这个接口的返回状态是500时的情况,可以请求这个地址
/actuator/metrics/http.server.requests?tag=uri:/actuator/metrics,status:500
根据tag进行筛选时,有两个情况需要注意:
availableTags
部分列出的时当前可用的tag的key和value。如果某个接口没有返回过500而你却查询tag=500的情况,则接口会报错curl
命令或postman之类的工具试试关于监控,我再啰嗦两句。
上面的接口每次请求,返回的都是当前的值,并且服务重启后,上面的值都会归零。
可以按照固定的频率重复请求actuator暴露的endpoint,并将每次请求的结果保存到时序数据库中(例如influxDB,或OpenTSDB),再用grafana来展示出来,是比较常用的监控套路。
关于http接口的设计,最糟糕的设计莫过于:所有的response的code都是200,而接口是否成功,以及errorMsg都在response的body中给出。基于这种设计做监控的成本极高。比较流行的设计是restful风格的http接口,并且不同的情况返回不同的http code,这样的话,我们就知道接口返回400、401、403、404、500等code的原因是不一样的,需要采取的行动也是不一样的。