监控
通过软件的方式展示另一个软件的运行情况,运行的情况则通过各种各样的指标数据反馈给监控人员。例如网络是否顺畅、服务器是否在运行、程序的功能是否能够整百分百运行成功,内存是否够用,等等。
监控的意义
- 监控服务状态是否处理宕机状态 服务是否正常运行
- 监控服务运行指标 比如内存占用严重,请求无法及时响应处理等
- 监控程序运行日志 在众多日志中找到开发者或运维人员所关注的日志信息,简单快速有效的过滤出要看的日志
- 管理服务状态 服务器被攻击、服务器内存溢出等情况造成了服务器宕机,此时当前服务不能满足使用需要,就要将其重启甚至关闭,快速控制服务器的启停 。
- 还有很多的细节点,例如上线了一个新功能,定时提醒用户续费,这种功能不是上线后马上就运行的,但是当前功能是否真的启动,如何快速的查询到这个功能已经开启,这也是监控中要解决的问题,等等。
总结
- 监控是一个非常重要的工作,是保障程序正常运行的基础手段
- 监控的过程通过一个监控程序进行,它汇总所有被监控的程序的信息集中统一展示
- 被监控程序需要主动上报自己被监控,同时要设置哪些指标被监控
可视化监控平台
Spring Boot Admin,这是一个开源社区项目,用于管理和监控SpringBoot应用程序。这个项目中包含有客户端和服务端两部分,而监控平台指的就是服务端。我们做的程序如果需要被监控,将我们做的程序制作成客户端,然后配置服务端地址后,服务端就可以通过HTTP请求的方式从客户端获取对应的信息,并通过UI界面展示对应信息。
服务端开发
步骤①:导入springboot admin对应的starter,版本与当前使用的springboot版本保持一致,并将其配置成web工程
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
上述过程可以通过创建项目时使用勾选的形式完成。
步骤②:在引导类上添加注解@EnableAdminServer,声明当前应用启动后作为SpringBootAdmin的服务器使用
@SpringBootApplication
@EnableAdminServer
public class Springboot25AdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot25AdminServerApplication.class, args);
}
}
客户端开发
客户端程序开发其实和服务端开发思路基本相似,多了一些配置而已。
步骤①:导入springboot admin对应的starter,版本与当前使用的springboot版本保持一致,并将其配置成web工程
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
上述过程也可以通过创建项目时使用勾选的形式完成,不过一定要小心,端口配置成不一样的,否则会冲突。
步骤②:设置当前客户端将信息上传到哪个服务器上,通过yml文件配置
spring:
boot:
admin:
client:
url: http://localhost:8080
由于当前没有设置开放哪些信息给监控服务器,所以目前看不到什么有效的信息。下面需要做两组配置就可以看到信息了。
- 开放指定信息给服务器看
- 允许服务器以HTTP请求的方式获取对应的信息
配置如下:
server:
port: 80
spring:
boot:
admin:
client:
url: http://localhost:8080
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: "*"
springbootadmin的客户端默认开放了13组信息给服务器,但是这些信息除了一个(健康信息)之外,其他的信息都不让通过HTTP请求查看。需要配置
通过配置就可以开放所有的健康信息明细查看了。
management:
endpoint:
health:
show-details: always
通过配置就可以开放所有的健康信息明细查看了。
```yaml
management:
endpoint:
health:
show-details: always
配置多个客户端
可以通过配置客户端的方式在其他的springboot程序中添加客户端坐标,这样当前服务器就可以监控多个客户端程序了。每个客户端展示不同的监控信息。
总结
- 开发监控服务端需要导入坐标,然后在引导类上添加注解@EnableAdminServer,并将其配置成web程序即可
- 开发被监控的客户端需要导入坐标,然后配置服务端服务器地址,并做开放指标的设定即可
- 在监控平台中可以查阅到各种各样被监控的指标,前提是客户端开放了被监控的指标
监控原理
通过查阅监控中的映射指标,可以看到当前系统中可以运行的所有请求路径,其中大部分路径以/actuator开头
访问这个路径
通过发送请求,可以得到一组json信息
点击查看代码
{
"_links": {
"self": {
"href": "http://localhost:81/actuator",
"templated": false
},
"beans": {
"href": "http://localhost:81/actuator/beans",
"templated": false
},
"caches-cache": {
"href": "http://localhost:81/actuator/caches/{cache}",
"templated": true
},
"caches": {
"href": "http://localhost:81/actuator/caches",
"templated": false
},
"health": {
"href": "http://localhost:81/actuator/health",
"templated": false
},
"health-path": {
"href": "http://localhost:81/actuator/health/{*path}",
"templated": true
},
"info": {
"href": "http://localhost:81/actuator/info",
"templated": false
},
"conditions": {
"href": "http://localhost:81/actuator/conditions",
"templated": false
},
"shutdown": {
"href": "http://localhost:81/actuator/shutdown",
"templated": false
},
"configprops": {
"href": "http://localhost:81/actuator/configprops",
"templated": false
},
"configprops-prefix": {
"href": "http://localhost:81/actuator/configprops/{prefix}",
"templated": true
},
"env": {
"href": "http://localhost:81/actuator/env",
"templated": false
},
"env-toMatch": {
"href": "http://localhost:81/actuator/env/{toMatch}",
"templated": true
},
"loggers": {
"href": "http://localhost:81/actuator/loggers",
"templated": false
},
"loggers-name": {
"href": "http://localhost:81/actuator/loggers/{name}",
"templated": true
},
"heapdump": {
"href": "http://localhost:81/actuator/heapdump",
"templated": false
},
"threaddump": {
"href": "http://localhost:81/actuator/threaddump",
"templated": false
},
"metrics-requiredMetricName": {
"href": "http://localhost:81/actuator/metrics/{requiredMetricName}",
"templated": true
},
"metrics": {
"href": "http://localhost:81/actuator/metrics",
"templated": false
},
"scheduledtasks": {
"href": "http://localhost:81/actuator/scheduledtasks",
"templated": false
},
"mappings": {
"href": "http://localhost:81/actuator/mappings",
"templated": false
}
}
}
其中每一组数据都有一个请求路径,而在这里请求路径中有之前看到过的health,发送此请求又得到了一组信息
{
"status": "UP",
"components": {
"diskSpace": {
"status": "UP",
"details": {
"total": 297042808832,
"free": 72284409856,
"threshold": 10485760,
"exists": true
}
},
"ping": {
"status": "UP"
}
}
}
当前信息与监控面板中的数据存在着对应关系
监控中显示的信息实际上是通过发送请求后得到json数据,然后展示出来。按照上述操作,可以发送更多的以/actuator开头的链接地址,获取更多的数据,这些数据汇总到一起组成了监控平台显示的所有数据。
Actuator,可以称为端点,描述了一组监控信息,SpringBootAdmin提供了多个内置端点,通过访问端点就可以获取对应的监控信息,也可以根据需要自定义端点信息。通过发送请求路劲/actuator可以访问应用所有端点信息,如果端点中还有明细信息可以发送请求/actuator/端点名称来获取详细信息。以下列出了所有端点信息说明:
ID | 描述 | 默认启用 |
auditevents | 暴露当前应用程序的审计事件信息。 | 是 |
beans | 显示应用程序中所有 Spring bean 的完整列表。 | 是 |
caches | 暴露可用的缓存。 | 是 |
conditions | 显示在配置和自动配置类上评估的条件以及它们匹配或不匹配的原因。 | 是 |
configprops | 显示所有 @ConfigurationProperties 的校对清单。 | 是 |
env | 暴露 Spring ConfigurableEnvironment 中的属性。 | 是 |
flyway | 显示已应用的 Flyway 数据库迁移。 | 是 |
health | 显示应用程序健康信息 | 是 |
httptrace | 显示 HTTP 追踪信息(默认情况下,最后 100 个 HTTP 请求/响应交换)。 | 是 |
info | 显示应用程序信息。 | 是 |
integrationgraph | 显示 Spring Integration 图。 | 是 |
loggers | 显示和修改应用程序中日志记录器的配置。 | 是 |
liquibase | 显示已应用的 Liquibase 数据库迁移。 | 是 |
metrics | 显示当前应用程序的指标度量信息。 | 是 |
mappings | 显示所有 @RequestMapping 路径的整理清单。 | 是 |
scheduledtasks | 显示应用程序中的调度任务。 | 是 |
sessions | 允许从 Spring Session 支持的会话存储中检索和删除用户会话。当使用 Spring Session 的响应式 Web 应用程序支持时不可用。 | 是 |
shutdown | 正常关闭应用程序。 | 否 |
threaddump | 执行线程 dump。 | 是 |
heapdump | 返回一个 hprof 堆 dump 文件。 | 是 |
jolokia | 通过 HTTP 暴露 JMX bean(当 Jolokia 在 classpath 上时,不适用于 WebFlux)。 | 是 |
logfile | 返回日志文件的内容(如果已设置 logging.file 或 logging.path 属性)。支持使用 HTTP Range 头来检索部分日志文件的内容。 | 是 |
prometheus | 以可以由 Prometheus 服务器抓取的格式暴露指标。 | 是 |
上述端点每一项代表被监控的指标,如果对外开放则监控平台可以查询到对应的端点信息,如果未开放则无法查询对应的端点信息。通过配置可以设置端点是否对外开放功能。使用enable属性控制端点是否对外开放。其中health端点为默认端点,不能关闭。
management:
endpoint:
health: # 端点名称
show-details: always
info: # 端点名称
enabled: true # 是否开放
为了方便开发者快速配置端点,springboot admin设置了13个较为常用的端点作为默认开放的端点,如果需要控制默认开放的端点的开放状态,可以通过配置设置,如下:
management:
endpoints:
enabled-by-default: true # 是否开启默认端点,默认值true
上述端点开启后,就可以通过端点对应的路径查看对应的信息了。但是此时还不能通过HTTP请求查询此信息,还需要开启通过HTTP请求查询的端点名称,使用“*”可以简化配置成开放所有端点的WEB端HTTP请求权限。
management:
endpoints:
web:
exposure:
include: "*"
整体上来说,对于端点的配置有两组信息,一组是endpoints开头的,对所有端点进行配置,一组是endpoint开头的,对具体端点进行配置。
management:
endpoint: # 具体端点的配置
health:
show-details: always
info:
enabled: true
endpoints: # 全部端点的配置
web:
exposure:
include: "*"
enabled-by-default: true
总结
- 被监控客户端通过添加actuator的坐标可以对外提供被访问的端点功能
- 端点功能的开放与关闭可以通过配置进行控制
- web端默认无法获取所有端点信息,通过配置开放端点功能
自定义监控指标
端点描述了被监控的信息,除了系统默认的指标,还可以自行添加显示的指标,下面就通过3种不同的端点的指标自定义方式来学习端点信息的二次开发。
INFO端点
info端点描述了当前应用的基本信息,可以通过两种形式快速配置info端点的信息
- 配置形式
在yml文件中通过设置info节点的信息就可以快速配置端点信息
info:
appName: @project.artifactId@
version: @project.version@
company: 传智教育
author: itheima
配置完毕后,对应信息显示在监控平台上
也可以通过请求端点信息路径获取对应json信息
- 编程形式
通过配置的形式只能添加固定的数据,如果需要动态数据还可以通过配置bean的方式为info端点添加信息,此信息与配置信息共存
@Component
public class InfoConfig implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
builder.withDetail("runTime",System.currentTimeMillis()); //添加单个信息
Map infoMap = new HashMap();
infoMap.put("buildTime","2006");
builder.withDetails(infoMap); //添加一组信息
}
}
Health端点
health端点描述当前应用的运行健康指标,即应用的运行是否成功。通过编程的形式可以扩展指标信息。
@Component
public class HealthConfig extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
boolean condition = true;
if(condition) {
builder.status(Status.UP); //设置运行状态为启动状态
builder.withDetail("runTime", System.currentTimeMillis());
Map infoMap = new HashMap();
infoMap.put("buildTime", "2006");
builder.withDetails(infoMap);
}else{
builder.status(Status.OUT_OF_SERVICE); //设置运行状态为不在服务状态
builder.withDetail("上线了吗?","你做梦");
}
}
}
当任意一个组件状态不为UP时,整体应用对外服务状态为非UP状态。
Metrics端点
metrics端点描述了性能指标,除了系统自带的监控性能指标,还可以自定义性能指标。
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
@Autowired
private BookDao bookDao;
private Counter counter;
public BookServiceImpl(MeterRegistry meterRegistry){
counter = meterRegistry.counter("用户付费操作次数:");
}
@Override
public boolean delete(Integer id) {
//每次执行删除业务等同于执行了付费业务
counter.increment();
return bookDao.deleteById(id) > 0;
}
}
在性能指标中就出现了自定义的性能指标监控项
自定义端点
可以根据业务需要自定义端点,方便业务监控
@Component
@Endpoint(id="pay",enableByDefault = true)
public class PayEndpoint {
@ReadOperation
public Object getPay(){
Map payMap = new HashMap();
payMap.put("level 1","300");
payMap.put("level 2","291");
payMap.put("level 3","666");
return payMap;
}
}
由于此端点数据spirng boot admin无法预知该如何展示,所以通过界面无法看到此数据,通过HTTP请求路径可以获取到当前端点的信息,但是需要先开启当前端点对外功能,或者设置当前端点为默认开发的端点。
总结
- 端点的指标可以自定义,但是每种不同的指标根据其功能不同,自定义方式不同
- info端点通过配置和编程的方式都可以添加端点指标
- health端点通过编程的方式添加端点指标,需要注意要为对应指标添加启动状态的逻辑设定
- metrics指标通过在业务中添加监控操作设置指标
- 可以自定义端点添加更多的指标