Service Mesh的架构设计中的要点之一,就是全方位的监控,因此一般我们选用的服务开发框架都需要有方便又强大的监控功能支持。在Spring boot应用中开启监控特别方便,监控面也很广,还支持灵活定制。
添加Actuator依赖
在Spring boot应用中,要实现可监控的功能,依赖的是 spring-boot-starter-actuator
这个组件。它提供了很多监控和管理你的spring boot应用的HTTP或者JMX端点,并且你可以有选择地开启和关闭部分功能。当你的spring boot应用中引入下面的依赖之后,将自动的拥有审计、健康检查、Metrics监控功能。
org.springframework.boot spring-boot-starter-actuator
具体的使用方法:
引入上述的依赖jar;
通过下面的配置启用所有的监控端点,默认情况下,这些端点是禁用的;
management: endpoints: web: exposure: include: "*" server: port: 10111 servlet: context-path: / ssl: enabled: false endpoint: health: show-details: always
“*”号代表启用所有的监控端点,可以单独启用,例如,health
,info
,metrics
等。
上述配置信息仅供参考,具体须参照官方文档,由于spring boot的版本更新比较快,配置方式可能有变化。
健康检查
当我们开启health
的健康端点时,我们能够查到应用健康信息是一个汇总的信息,访问http://127.0.0.1:10111/actuator/health
时,我们获取到的信息是{"status":"UP"}
,status的值还有可能是 DOWN。
要想查看详细的应用健康信息需要配置management.endpoint.health.show-details
的值为always
,配置之后我们再次访问http://127.0.0.1:10111/actuator/health
,获取的信息如下:
{ "status": "UP", "details": { "diskSpace": { "status": "UP", "details": { "total": 250685575168, "free": 172252426240, "threshold": 10485760 } }, "redis": { "status": "UP", "details": { "version": "3.2.11" } }, "db": { "status": "UP", "details": { "database": "Oracle", "hello": "Hello" } } }}
从上面的应用的详细健康信息发现,健康信息包含磁盘空间、redis、DB,启用监控的这个spring boot应用确实是连接了redis和oracle DB,actuator就自动给监控起来了,确实是很方便、很有用。
经过测试发现,details中所有的监控项中的任何一个健康状态是DOWN
,整体应用的健康状态也是DOWN
。
management.endpoint.health.show-details
的值除了always
之外还有when-authorized
、never
,默认值是never
。
健康检查的原理
Spring boot的健康信息都是从ApplicationContext
中的各种HealthIndicator
Beans中收集到的,Spring boot框架中包含了大量的HealthIndicators
的实现类,当然你也可以实现自己认为的健康状态。
默认情况下,最终的spring boot应用的状态是由HealthAggregator
汇总而成的,汇总的算法是:
设置状态码顺序:
setStatusOrder(Status.DOWN, Status.OUT_OF_SERVICE, Status.UP, Status.UNKNOWN);
。过滤掉不能识别的状态码。
如果无任何状态码,整个spring boot应用的状态是
UNKNOWN
。将所有收集到的状态码按照 1 中的顺序排序。
返回有序状态码序列中的第一个状态码,作为整个spring boot应用的状态。
源代码请参见:
org.springframework.boot.actuate.health.OrderedHealthAggregator
。
Spring boot框架自带的 HealthIndicators
目前包括:
Name | Description |
---|---|
CassandraHealthIndicator | Checks that a Cassandra database is up. |
DiskSpaceHealthIndicator | Checks for low disk space. |
DataSourceHealthIndicator | Checks that a connection to DataSource can be obtained. |
ElasticsearchHealthIndicator | Checks that an Elasticsearch cluster is up. |
InfluxDbHealthIndicator | Checks that an InfluxDB server is up. |
JmsHealthIndicator | Checks that a JMS broker is up. |
MailHealthIndicator | Checks that a mail server is up. |
MongoHealthIndicator | Checks that a Mongo database is up. |
Neo4jHealthIndicator | Checks that a Neo4j server is up. |
RabbitHealthIndicator | Checks that a Rabbit server is up. |
RedisHealthIndicator | Checks that a Redis server is up. |
SolrHealthIndicator | Checks that a Solr server is up. |
你可以通过
management.health.defaults.enabled
这个配置项将它们全部禁用掉,也可以通过management.health.xxxx.enabled
将其中任意一个禁用掉。
自定义 HealthIndicator 健康检查
有时候需要提供自定义的健康状态检查信息,你可以通过实现HealthIndicator
的接口来实现,并将该实现类注册为spring bean。你需要实现其中的health()
方法,并返回自定义的健康状态响应信息,该响应信息应该包括一个状态码和要展示详细信息。例如,下面就是一个接口HealthIndicator
的实现类:
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; @Componentpublic class MyHealthIndicator implements HealthIndicator { @Override public Health health() { int errorCode = check(); // perform some specific health check if (errorCode != 0) { return Health.down().withDetail("Error Code", errorCode).build(); } return Health.up().build(); }}
另外,除了Spring boot定义的几个状态类型,我们也可以自定义状态类型,用来表示一个新的系统状态。在这种情况下,你还需要实现接口 HealthAggregator
,或者通过配置 management.health.status.order
来继续使用HealthAggregator
的默认实现。
例如,在你自定义的健康检查HealthIndicator
的实现类中,使用了自定义的状态类型FATAL
,为了配置该状态类型的严重程度,你需要在application的配置文件中添加如下配置:
management.health.status.order=FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP
在做健康检查时,响应中的HTTP状态码反应了整体的健康状态,(例如,UP
对应 200, 而 OUT_OF_SERVICE
和 DOWN
对应 503)。同样,你也需要为自定义的状态类型设置对应的HTTP状态码,例如,下面的配置可以将 FATAL
映射为 503(服务不可用):
management.health.status.http-mapping.FATAL=503
如果你需要更多的控制,你可以定义自己的
HealthStatusHttpMapper
bean。
下面是内置健康状态类型对应的HTTP状态码列表:
Status | Mapping |
---|---|
DOWN | SERVICE_UNAVAILABLE (503) |
OUT_OF_SERVICE | SERVICE_UNAVAILABLE (503) |
UP | No mapping by default, so http status is 200 |
UNKNOWN | No mapping by default, so http status is 200 |
Actuator监控分成两类:原生端点和用户自定义扩展端点,原生的主要有:
路径 | 描述 |
---|---|
/autoconfig | 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过 |
/beans | 描述应用程序上下文里全部的Bean,以及它们的关系 |
/env | 获取全部环境属性 |
/configprops | 描述配置属性(包含默认值)如何注入Bean |
/dump | 获取线程活动的快照 |
/health | 报告应用程序的健康指标,这些值由HealthIndicator的实现类提供 |
/info | 获取应用程序的定制信息,这些信息由info打头的属性提供 |
/mappings | 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系 |
/metrics | 报告各种应用程序度量信息,比如内存用量和HTTP请求计数 |
/shutdown | 关闭应用程序,要求endpoints.shutdown.enabled设置为true |
/trace | 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等) |
安全措施
如果上述请求接口不做任何安全限制,安全隐患显而易见。实际上Spring Boot也提供了安全限制功能。比如要禁用/env接口,则可设置如下:
endpoints.env.enabled= false
如果只想打开一两个接口,那就先禁用全部接口,然后启用需要的接口:
endpoints.enabled = falseendpoints.health.enabled = true
另外也可以引入spring-boot-starter-security依赖
org.springframework.boot spring-boot-starter-security
在application.properties中指定actuator的端口以及开启security功能,配置访问权限验证,这时再访问actuator功能时就会弹出登录窗口,需要输入账号密码验证后才允许访问。
management.port=8099management.security.enabled=truesecurity.user.name=admin security.user.password=admin
actuator暴露的health接口权限是由两个配置: management.security.enabled
和 endpoints.health.sensitive
组合的结果进行返回的。