SpringBoot应用监控解析:Actuator实现原理
wptr33 2024-12-07 17:44 24 浏览
Spring Boot 应用监控解析
在企业应用中除了要了解 Spring Boot 业务的单元测试、集成测试等功能使用外,在上线之后还需要对线上应用的各项指标(比如,CPU 利用率、内存利用率、数据库连接是否正常、用户请求数据等)进行监控和运维。
在传统项目中,这些监控和运维往往需要借助其他第三方的工具实现,而在 Spring Boot 中提供了 spring-boot-actuator 模块,可以通过 http、jmx、 ssh、telnet 等形式来监控和管理生产环境。同时,Spring Boot 还提供了灵活的自定义接口用来扩展监控的功能。
本章不会过多涉及 actuator 基础使用,而是重点绍 actuator 的自动配置及实现原理。
Actuator 简介
Spring Boot Actuator 提供了应用的审计(Auditing) 、健康(Health) 状态信息、数据采集(Metrics gathering)统计等监控运维的功能。同时,还提供了可扩展的端点(Endpoint) 功能,方便使用者进行自定义监控指标。默认情况下,这些信息以 JSON 的数据格式呈现,用户也可以使用 Spring BootAdmin 项目进行界面管理。
Spring Boot Actuator 通常使用下面的 starter 引入。
<dependency>
<groupId>org. springframework . boot</groupId>
<artifactId>spring- boot -starter-actuator</artifactId>
</ dependency>
通过上面的 starter 会间接引入以下两个依赖。
<dependency>
<groupId>org. springframework . boot</groupId>
<artifactId>spring- boot- actuator</ artifactId>
</ dependency>
<dependency>
<groupId>org. springfr amework . boot</ groupId>
<artifactId>spring- boot- actuator autoconfigure</ artifactId>
</ dependency>
在 Spring Boot 项目中,spring-boot-actuator 作为一 个独立的项目,提供 Actuator 的核心功能,spring-boot-actuator-autoconfigure 提供 了 Actuator 自动配置的功能。
引入 spring-boot- starter-actuator 之后,默认情况下便开启了监控功能,我们可通过http://localhost:8080/actuator 来查看默认支持的监控信息。
通过浏览器访问,上述请求地址,默认返回结果信息如下。
{
_links":
"self": {
"href": "http://localhost: 8080/actuator",
"templated": false
},
"health-path": {
"href": "http://localhost: 8080/ actuator/health/{*path}",
"templated": true
"health": {
"href": "http://localhost :8080/ actuator/health" ,"templated": false
},
"info": {
"href": "http://localhost : 8080/actuator/info",
"templated": false
}
}
}
默 认 情 况 下 , 上 述 返 回 信 息 对 应 的 监 控 处 于 开 启 状 态 , 使 用 者 也 可 以 在application.properties 中进行配置来禁用或开启具体的监控。
#启用 shutdown
management . endpoint . shutdown. enabled=true
#全部禁用
management . endpoints . enabled-by-default=false
s 启用 info
management . endpoint. info. enabled=true
了解了监控的基本集成和配置,下面重 点讲解一下 Actuator 的自动配置及原理。
Actuator 自动配置
关于 Actuator 自动配置,我们以 HealthEndpoint 为例, 了解一下在 SpringBoot 中是如何进行自动配置并获取到对应的监控信息的。同时,也简单了解一下,这些自动配置组件获得的信息是如何通过 URL 访问展示出来的。
HealthEndpoint 自动配置
Actuator 的自动配置默认没有在 Spring Boot Autoconfigure 中集成,而是通过独立的spring-boot actuator- autoconfigure 项目来实现。在该项目中实现了大量关于不同组件监控的自动配置。
在继续本章学习或将 Spring Boot 版本升级之前,需提醒读者注意对照所使用的 Spring BootActuator 的版本,因为从 Spring Boot 2.0.x 到 2.2.x 版本,关于 Actuator 及其自动配置的实现代码发生了比较大的变动。
本节以监控点(Health) 相关的自动配置源码及实现原理为例进行讲解,步及的自动配置类有HealthEndpointAutoConfigurationHealthEndpointConfiguration 等。关于 Health 的相关类均位于 org.springframework.boot.actuate .autoconfigure.health 包下。
Actuator 的 自 动 配 置 类 的 注 册 都 是 在 spring-boot-actuator-autoconfigure 项 目 下 的spring.factories 中完成的。HealthEndpointAutoConfiguration 也不例外,源码如下。
@Configuration(proxyBeanMethods = false)@ConditionalOnAvailableEndpoint (endpoint = HealthEndpoint . class)
@EnableConfigurationProperties
@Import({ LegacyHealthEndpointAdaptersConfiguration. class, LegacyHealthEndpoint-
CompatibilityConfiguration. class,
HealthEndpointConfiguration. class, ReactiveHealthEndpointConfiguration. class,
HealthEndpointWebExtens ionConfiguration. class, HealthEndpointReactive-
WebExtens ionConfiguration.class })
public class HealthEndpointAutoConfiguration {
@Bean
@SuppressWarnings("deprecation")
HealthEndpointProperties healthEndpointProperties (HealthIndicatorProperti
es healthIndicatorPrope
rties) {
HealthEndpointProperties healthEndpointProperties = new HealthEndpoint -
Properties();
healthEndpointProperties . getStatus(). getOrder(). addAll(healthIndicator-
Properties . get0r
der());
healthEndpointProperties . getStatus(). getHttpMapping() . putAll(healthIn-
dicatorPro
perties . getHttpMapping());
return healthEndpointProperties;
}
}
@Configuration 开启了自动配置。@ConditionalOnAvailableEndpoint 为 Spring Boot 2.2版本新引入的注解,表示 HealthEndpoint 的 endpoint 仅在可用时才会进行自动化配置。那么什么情况是可用的呢?这里的可用指的是某一个 endpoint 必须满足是可用状态(enabled)和暴露的(exposed) 。
@EnableConfigurationProperties 开启了健康检查端点、健康检查指示器的属性配置,
@Import 引入了 多个自动装载类,下面会具体讲解。
HealthEndpointAutoConfiguration 类本身在 Spring Boot 2.1 版本之前并没有具体的代码实现,当前版本虽然添加了对 HealthEndpointProperties 配置类的实例化操作,但它所依赖的HealthIndicatorProperties 参数已被标记为过时的,并被 HealthEndpointProperties 所代替,目前不确定后续版本是否会有新的变化。
在HealthEndpointAutoConfiguration的@Import中LegacyHealthEndpointAdaptersConfiguration和LegacyHealthEndpointCompatibilityConfiguration 都是为了兼容旧版版本而提供的自动配置,ReactiveHealthEndpointConfiguration和HealthEndpointReactiveWebExtensionConfiguration 是针对 Reactive 的操作。
这里重点介绍HealthEndpointConfiguration和HealthEndpointWebExtensionConfiguration.
前 者 是 /health 端 点 的 基 础 配 置 , 后 者 为 针 对 web 的 扩 展 配 置 。 我 们 先 看HealthEndpoint-Configuration 的源代码。
@Configurat ion(proxyBeanMethods = false)d.5)
class HealthEndpointConfi guratior
//实例化 StatusAggregator, heal th 状态聚合器
@Bean
@ConditionalOnMissingBean
StatusAggregator healthStatusAggregator(HealthEndpointProperties properti
es
//默认采用其 SimpleStatusAggregator 实现,如果未指定 status,则默认集合 Stat
us 类中定义的所有状态集合
return new SimpleStatusAggregator(properties . getStatus(). get0rder());
//实例 fCHttpCodeStatusMapper, 用于映射 Heal th.到 Http 的状态码
@Bean
@Condit ionalOnMissingBean
HttpCodeStatusMapper healthHttpCodeStatusMapper(HealthEndpointProperties
F_ SERVICE 到 HTTP 的 503
odestatuSMapper 买现,
映射 Status . DOWN 和 Status.OUT 0
return new SimpleHttpCodeStatusMapper(properties . getStatus() . getHttpMap
ping());
//实例 CHeal thEndpointGroups,用 FHeal thEndpointGroup 的集合操作
@Bear
@ConditionalOnMissingBean
HealthEndpointGroups healthEndpointGroups(ApplicationContext applicationC
ontext,
HealthEndpointProperties prope
rties) {
采用 AutoConfiguredHeal thEndpointGroups 实现,该类主要没置其属性 primaryroup
return new AutoConfiguredHealthEndpointGroups ( applicat ionContext, properties);
// 实 例 CHeal thContributorRegistry, 用 FHeal thContributor 的 可 变 注 册@ConditionalOnMissingBean
HealthContributorRegi stry
plicationContext,
HealthEndpointGroups
groups) {
Map<String, HealthContributor> healthContributors = new LinkedHashMap<>
applicationContext. getBeansOfType(HealthContributor . class));
// 如 果 类 路 径 下 存 在 reactor. core . publ isher. Flux 类 , 则 添 力 Reactive 相 关 的
AdaptedReact-
iveHealthContributors
if (ClassUtils. isPresent( "reactor . core . publisher. Flux",applicationCont
ext.
getClassLoader())) {
healthContributors. putAll(new AdaptedReactiveHealthContributors(ap-
plica
tionContext).get());
//采用 HealthContributorRegistry 实现类,磅保注册的注册器不与 group 的名字冲
return new AutoConf iguredHealthContributorRegistry(healthContributors,
groups . getNames());
//实例化 Heal thEndpoint,用户暴露应用程序的健康信息
@Bear
@Condit ionalOnMissingBean
HealthEndpoint healthEndpoint(Heal thContr ibutorRegistry registry, HealthE
ndpoint
Groups groups) {
return new HealthEndpoint(registry, groups);
省略内部类 AdaptedReactiveHeal thContributors 相关代码,用 FReactiveHea
l thContributor
的适配器
}
首先,HealthEndpointConfiguration 的注解中并无其他条件注解,这说明该类并非利用自动配置机制来进行配置,而是一旦引入就会直接被@Configuration 注解实例化。
其 次 , 该 类 中 内 部 主 要 实 例 化 了StatusAggregator、HttpCodeStatusMapperHealthEndpoint-GroupsHealthContributorRegistry和HealthEndpoint 相关的基础组件。
其中,StatusAggregator 接口提供 了根据传入的系统状态集合(Status 集合)获取具体状态的功能,在 Status 中定义了 UNKNOWN、UP、DOWN、OUT_ OF_ SERVICE 这 4 种状态。
而 HttpCodeStatusMapper 接口提供了根据 Status 获得的 Http 状态码,也就是用于监控状态到 Http 状态码的映射功能。关于其他组件的具体实例化操作及功能简介,可配合代码中的注释进行源代码阅读,这里不再展开。
下面看 HealthEndpointWebExtensionConfiguration,该配置类代码相对简单,源代码如下。
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type . SERVLET)
@ConditionalonBean(HealthEndpoint. class)
class HealthEndpointWebExtensionConfiguration {
@Bean
@ConditionalOnBean(HealthEndpoint. class)
@ConditionalOnMissingBean
HealthEndpointWebExtension healthEndpointWebExtension(HealthContri butorRe
g-
istry healthContrib
utorRegistry,
HealthEndpointGroup
s groups) {
return new HealthEndpointWebExtension(healthContributorRegistry, group
s);
}
}
该 自 动 配 置 的 主 要 作 用 是 针 对 HealthEndpoint 的 web 扩 展 , 注 解 中@ConditionalOn-WebApplication 表明只有应用类型为 Servlet 时,该类才会被配置,@ConditionalOnBean 表明当存 在 HealthEndpoint 的 Bean 时才会生效。
HealthEndpointWebExtensionConfiguration内部只初始化了HealthEndpointWebExtension对 象 , 创 建 该 Bean 的 条 件 为 : 容 器 中 存 在 HealthEndpoint 的 对 象 时 , 且HealthEndpoint-WebExtension 对象并不存在时。
HealthEndpointWebExtension 继承自 HealthEndpointSupport,主要用来提供 health 端点和health 端点扩展的基础类。
关于自动配置类,我们就讲这么多,读者可进一步阅读其他相关功能的源代码。下一 节我们将了解 HealthIndicator 的实现。
HealthIndicator 实现
上一节我们学习了 Health 相关的自动配置,那么 关于 Health 的信息是如何获得的呢?这就涉及 HealthIndicator 接口的功能了。
HealthIndicator 是一个策略模式的接口,继承自接口 HealthContributor.HealthContributor接口中并没有具体的方法定义,这是 Spring Boot 2.2.0 版本中新增的一个标记接口,作用于 HealthEndpoint 返回的 health 相关信息。相关的参与者必须为 HealthIndicator 或CompositeHealthContributor。
在 HealthIndicator 接口中定义了一个具有默认实现的 getHealth 方法和抽象的 health 方法,其中 getHealth 方法也是 Spring Boot 2.2.0 版本新增的。
HealthIndicator 接口源代码如下。
@FunctionalInterface
public interface HealthIndicator extends HealthContributor {
//根据 includeDetails,返回 health 指示
default Health getHealth(boolean includeDetails) {
Health health = health();
//如果 includeDetails 为 true 则直接返@health,否则返 回不携带洋情的 health
return includeDetails ? health : health . withoutDetails();
//返回 health 指示
Health health();
}
其中,health 方法返回 Health 对象,存储着应用程序的健康信息。
getHealth 方法会根据 includeDetails 参数判断是直接返回 health 方法的结果,还是返回经过处理不携带详情的 Health 对象。
常见的 HealthIndicator 实现,比如 JDBC 数据源( DataSourceHealthIndicator )磁盘健康指示器(DiskSpaceHealthIndicator)、Redis 健康 (RedisHealthIndicator) 等。
HealthIndicator 接 口 的 实 例 是 如 何 创 建 的 呢 ? 我 们 以 JDBC 数 据 源 的DataSourceHealth-Indicator 为 例 。 首 先 DataSourceHealthIndicator 继 承AbstractHealthIndicator, AbstractHealthIndicator 又 实现了 HealthIndicator 接口,也就是说 DataSourceHealthIndicator 是 HealthIndicator 类型。
DataSourceHealthIndicator的实例化是通过DataSourceHealthContributorAutoConfiguration 来完成的,相关源代码如下。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ JdbcTemplate. class, AbstractRoutingDataSource.class
})@ConditionalOnBean(DataSource. class)
@ConditionalOnEnabledHealthIndicator("db")
@AutoConfigureAfter (DataSourceAutoConfiguration. class)
public class DataSourceHealthContributorAutoConfiguration extends
CompositeHealthContributorConfiguration<AbstractHealthIndicator, DataSource>
implements InitializingBean {
//实例化 Heal thContributor
@Bean
@Condit ionalOnMissingBean(name = { "dbHealthIndicator", "dbHea lthContribu
tor" })
public HealthContributor dbHealthContributor(Map<String, DataSource> data
Sources) {
//主要通过 DataSource 数据源通过反射生成 Heal thContributor,
//这里通过父类 CompositeHeal thContributorConfigurat ion 的 createContributor
方法进行调用
// 当前类重写的 create Indicator 方法
return createContributor(dataSources);
//实例化对应的 AbstractHealthIndicator, 重 写父类 createIndicator 方法
@Override
protected AbstractHealthIndicator createIndicator(DataSource source) {
if (source instanceof AbstractRout ingDataSource) {
return new RoutingDataSourceHealthIndicator();
}
//实例化 DataSourceHealthIndicator, 参数数据源和查询语句
return new DataSourceHealthIndicator(source, getValidationQuery(sourc
e));
//获取检测所需的查询语句
private String getValidationQuery (DataSource source) {
//获取 DataSourcePooLMetadata 对象, 并 调用其 getVal idationQuery 方法
// getVal idationQuery 方法用来获得执行验证数据库链接是否正常的 SQL
DataSourcePoolMetadata poolMetadata = this . poolMetadataProvider . getDa-
taSourcePoolMetadata(source);
return (poolMetadata != null) ? poolMetadata. getValidationQuery() : null;
}。。。
}
关于 DataSourceHealthContributorAutoConfiguration 自动配置生效的条件就不详细解释了,在其内部可以看到,通过 createlndicator 方法实现了 DataSourceHealthIndicator 的实例化操作。该方法并没有直接被调用,而是通过 dbHealthContributor 方法调用父类的方法实现间接调用的。
DataSourceHealthIndicator 的构造方法有两个参数:一个数据源对象,一个 query 语句。 在该类中实现数据源健康检查的基本原理就是通过数据源连接数据库并执行相应的查询语句来验证连接是否正常。
其中 query 语句先通过数据源获得 DataSourcePoolMetadata 对象,如果对象不为 null,再通过对象的 getValidationQuery 方法进行获得,而 getValidationQuery 方法的具体实现通常由不同的数据源(DataSource) 来提供方法返回。
再看一- 下 DataSourceHealthIndicator 的核心代码。
public class DataSourceHealthIndicator extends AbstractHealthIndicator Q
implements InitializingBean {
private static final String DEFAULT QUERY = "SELECT 1";
private DataSource dataSource;
private String query;
private JdbcTemplate jdbcTemplate;
//监控检测的入口方法
@Override
protected void doHealthCheck(Health. Builder builder) throws Exception {
if (this .dataSource == null)
/如果数据源不存在,则返@unknown
builder . up().withDetail(" database", "unknown");
else {
//如果数据存在,则进行相应的检测操作
doDataSourceHealthCheck(builder);
private void doDataSourceHealthCheck(Health. Builder builder) throws Exception
//获取数据库名称
String product = getProduct();
builder. up() .withDetail("database", product);
//根据数据库名称获取对应的验证语句
String validationQuery = getValidationQuery(product);
if (StringUtils .hasText(validationQuery))
//避免在 Java 7 上破坏 MySQL 的情况下调用 getObject
//通过 jdbc Template 执行该 SQL 语句
List<Object> results = this . jdbcTemplate . query(validat ionQuery ,
new SingleColumnRowMapper());1 对查询结果进行处理
object result = DataAccessUtils . requiredSingleResult(results);
//结果存入 Health 中
builder .withDetail("hello", result);
//根据数据库名称获取对应的验证语句
protected String getValidationQuery(String product) {
String auery = this. auery:
if (!StringUtils. hasText(query)) {
//如果查询语句为指定,则根据数据库名称从枚举类 DatabaseDriver 中获取默认
的 sQL 语句
DatabaseDriver specific = DatabaseDriver . fromProductName( product);
query = specific . getValidat ionQuery();
if (!StringUtils. hasText(query)) {
i/如果以上情况都不存在, 则采用“SELECT 1”
query= DEFAULT OUERY:
query
return query;
}
}
doHealthCheck 为检测的入口方法,当数据源存在时调用 doDataSourceHealthCheck 方法,doDataSourceHealthCheck 方 法中会执行一个查询语句,并将结果存入 Health.Builder 中。
关于查询的 SQL 语句,如果通过构造方法传入了非 nul 的值,则使用该值;如果没有传入,则默认获取枚举类 DatabaseDriver 中定义的;如果该枚举类中也没有定义,则默认使用DataSourceHealthIndicator 中定义的常量 DEFAULT_ QUERY 的值(SELECT1)。
最后,我们看一下 DatabaseDriver 中默认定义的常见数据库的名称与对应的驱动类等信息。
public enum DatabaseDriver {
/ Unknown 类型
UNKNOWN(nul1, nu1l),
// Apache Derby.
DERBY("Apache Derby", "org. apache . derby . jdbc . EmbeddedDriver", "org. apach
e. derby. jdbc . EmbeddedXADataSource",
"SELECT 1 FROM SYSIBM. SYSDUMMY1"),
// H2
H2("H2", "org.h2 .Driver", "org.h2. jdbcx. JdbcDataSource", "SELECT 1"),
// HyperSQL DataBase.
HSQLDB( "HSQL Database Engine", "org. hsq1db. jdbc. JDBCDriver", "org. hsqldb.jdbc . pool. JDBCXADataSource" ,
"SELECT COUNT(*) FROM INFORMATION_ SCHEMA. SYSTEM_ _USERS"),
// sQL Lite
SQLITE("SQLite", "org. sqlite .JDBC"),
// MySQL
MYSQL("MySQL", "com. mysql. cj . jdbc . Driver", "com. mysql . cj . jdbc . MysqlXAData
Source", "/* ping */ SELECT 1"),
// Oracle.
ORACLE("Oracle", "oracle. jdbc . OracleDriver", "oracle. jdbc.xa. client . Oracl
eXADataSource",
"SELECT 'Hello' from DUAL"), }
上述代码只是列出了部分常见的数据库的默认定义,枚举类 DatabaseDriver 中还定义了其他数据源的默认信息,读者可阅读该类获得相应数据库的默认信息进行进一步学习。
经过上述部署,获得了对应数据库的 SQL 语句,然后通过 jdbcTemplate 执行该 SQL 语句,获得执行结果,再通过 DataAccessUtils 的 requiredSingleResult 方法校验并获取结果中的信息,最后存入 Health 中。
至此,Health 的信息获取便完成了,关于获取其他组件的 Health 信息读者可参照_上述解析过程自行学习。
Actuator 端点展示
在上一节,我们学习了关于健康检查的自动配置和基础信息的初始化操作,那么它又是如何实现通过 url 来进行相关检查结果信息的展示呢?这节我们以 Info 和 Health 的访问实现来学习 Actuator 的实现过程。
在spring-boot-actuator中,定义了@Endpoint注解。@Endpoint注解用来声明一-个actuator端点,被注释的类会被声明为提供应用程序信息的端点,可以通过各种技术(包括 JMX 和HTTP)来公开端点。
大 多 数 @Endpoint 类 会 声 明 一 个 或 多 个 @ReadOperation 、 @WriteOperation 、@DeleteOperation 注 解的方法,这些方法将自动适应公开技术(JMX、Spring MVC、SpringWebFlux、Jersey 等) 。同时还支持自定义的扩展。
以 info 为例,通过@Endpoint(id="info")暴 露了/actuator/info 访问接口。访问请求的基本格式如下。
http://ip:port/actuator/infoInfoEndpoint 的核心代码如下。
@Endpoint(id = "info")
public class InfoEndpoint {
@ReadOperationpublic Map<String, Object> info() {
Info. Builder builder = new Info . Builder();
for (InfoContributor contributor : this . infoContributors) {
contributor . contribute(builder);
Info build = builder . build( )
();
return build. getDetails();
}
}
通过@Endpoint(id="info")注解声明了该类为 info 的端点,并且遍历通过构造方法设置的infoContributors 值,然后返回对应的结果信息。默认访问/actuator/info 便可获得信息。
HealthEndpoint 也使用了@Endpoint 注解,在其内部通过@ReadOperation 注解映射了两个方法: health 方 法和 healthForPath 方法。
HealthEndpoint 的源码实现如下。
@Endpoint(id = "health")
public class HealthEndpoint extends HealthEndpointSupport<HealthContributr, HealthComponent>
private static final String[] EMPTY_ PATH = {};
@ReadOperation
public HealthComponent health() {
HealthComponent health = health(ApiVersion.V3, EMPTY_ PATH);
return (health != null) ? health : DEFAULT_ HEALTH;
@ReadOperation
public HealthComponent healthForPath(@Selector(match = Match. ALL_ REMAIN
ING)
String... path) {
return health(ApiVersion.V3, path);
}
}
HealthEndpoint 在 Spring Boot 2.2.0 版 本 中 变 化 比 较 大 , 新 增 继 承 了HealthEndpointSupport 类,并且方法的返回值由原来的 Health 变为 HealthComponent。.
上 面源代码中 ApiVersion.V3 针对的就是 Spring Boot2.2+版本提供的实现方式。
HealthEndpoint 原来直接接收 HealthIndicator 参数的构造方法也被标识为过时的。推荐使用以 HealthContributorRegistry 和 HealthEndpointGroups 为参数的构造方法,同时引入了group 的操作。
HealthEndpoint 的特殊之处在于:当通过 debug 模式访问/actuator/health 时,你会发现该请求 并 未 走 到 HealthEndpoint 的 health 方 法 。 这 是 因 为 基 于 Web 的 实 现 放 在 了HealthEndpointWebExtension 中。HealthEndpointWebExtension 同样继承 HealthEndpointSupport 类,并提供了两个对应的@ReadOperation 注解方法。
EndpointWebExtension(endpoint = Health
nEndpoint.class)
t. class)
public class HealthEndpointWebExtension extends HealthEndpointSupport<Healt
Contr
HealthComponent> {
@ReadOperation
public WebEndpointResponse<HealthComponent> health(ApiVersion apiVersion,
SecurityContext securi
tyContext) {
return health(apiVersion, securityContext, false, NO_ PATH);
@ReadOperation
public WebEndpointResponse<HealthComponent> health(ApiVersion apiVersion,
SecurityContext securi
tyContext,
@Selector(match = Matc
h.ALL REMAINING) String... path) {
return health(apiVersion, securityContext, false, path);} ....
}
以 health 方法为例,会调用父类的 getHealth 方法,经过一系列父类方法 的调用和业务处理,最终会调用父类的 getStatus 方法,此方法返回 HealthComponent 的 status,也就是默认情况下在浏览器访问时看到的 status 为 UP 的默认结果。
同样的,如果需要自定义可访问的 Endpoint,只需要在新建的 Bean.上使用@Endpoint 注解,该 Bean 中的方法就可以使用 JMX 或者 HTTP 公开,具体内部信息的获取实现可参看 SpringBoot 已实现的代码。除此之外,如果只需公开一种形式的访问,可使用@JmxEndpoint 或@WebEndpoint 注解。
至此,关于 Health 信息的 URL 访问呈现过程便完成了。
小结
本章重点介绍了 Actuator 的自动配置及实现原理。在 Actuator 中还提供了大量其他类型的监控组件(可查看 spring-boot-actuator-autoconfigure 项目下 spring.factories 中的注册),读者可根据本章节的分析思路进行分析。同时,也可尝试根据具体的业务自定义一个检查指示器进行体验。
本文给大家讲解的内容是SpringBoot应用监控解析:Actuator的自动配置及实现原理
- 下篇文章给大家讲解的是SpringBootSecurity 支持;
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持!
相关推荐
- MySQL进阶五之自动读写分离mysql-proxy
-
自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...
- 3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?
-
引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...
- 一文由浅入深带你完全掌握MySQL的锁机制原理与应用
-
本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...
- 验证Mysql中联合索引的最左匹配原则
-
后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...
- MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
-
目录1.索引基础...
- 你会看 MySQL 的执行计划(EXPLAIN)吗?
-
SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...
- MySQL 从入门到精通(四)之索引结构
-
索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...
- mysql总结——面试中最常问到的知识点
-
mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...
- mysql总结——面试中最常问到的知识点(2)
-
首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...
- MySQL基础全知全解!超详细无废话!轻松上手~
-
本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...
- 深入剖析 MySQL 中的锁机制原理_mysql 锁详解
-
在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...
- Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析
-
引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...
- MySQL基础篇:DQL数据查询操作_mysql 查
-
一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...
- MySql:索引的基本使用_mysql索引的使用和原理
-
一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
程序员的开源月刊《HelloGitHub》第 71 期
-
详细介绍一下Redis的Watch机制,可以利用Watch机制来做什么?
-
假如有100W个用户抢一张票,除了负载均衡办法,怎么支持高并发?
-
Java面试必考问题:什么是乐观锁与悲观锁
-
如何将AI助手接入微信(打开ai手机助手)
-
redission YYDS spring boot redission 使用
-
SparkSQL——DataFrame的创建与使用
-
一文带你了解Redis与Memcached? redis与memcached的区别
-
如何利用Redis进行事务处理呢? 如何利用redis进行事务处理呢英文
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)