如何从代码获取Spring Boot的/actuator/quartz指标实现存活健康指示器?
实现基于Quartz触发器时间的Spring Boot健康指示器
问题背景
需要实现一个健康指示器,在Spring Boot 2.6.7应用内部获取Quartz触发器的previousFireTime和nextFireTime信息,以此检测Job的execute方法随机停止执行的问题。此前尝试从MeterRegistry获取Quartz相关指标但未找到。
解决方案步骤
1. 启用Quartz Actuator端点(可选)
若要依赖Actuator端点数据,先在配置文件中开启Quartz端点:
management.endpoints.web.exposure.include=quartz management.endpoint.quartz.enabled=true
2. 直接通过Quartz核心API获取触发器信息(推荐)
不依赖Actuator端点,直接调用Quartz调度器API获取实时触发时间,更可靠且无端点暴露限制:
import org.quartz.*; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; import java.time.Instant; import java.time.temporal.ChronoUnit; @Component public class QuartzJobHealthIndicator implements HealthIndicator { private final Scheduler scheduler; // 注入Quartz调度器实例 public QuartzJobHealthIndicator(Scheduler scheduler) { this.scheduler = scheduler; } @Override public Health health() { Health.Builder healthBuilder = Health.up(); try { // 替换为你的Job对应的触发器组和名称 String triggerGroup = "YOUR_TRIGGER_GROUP"; String triggerName = "YOUR_TRIGGER_NAME"; Trigger trigger = scheduler.getTrigger(new TriggerKey(triggerName, triggerGroup)); if (trigger != null) { // 转换为Instant类型便于时间计算 Instant previousFireTime = trigger.getPreviousFireTime() != null ? trigger.getPreviousFireTime().toInstant() : null; Instant nextFireTime = trigger.getNextFireTime() != null ? trigger.getNextFireTime().toInstant() : null; healthBuilder.withDetail("previousFireTime", previousFireTime); healthBuilder.withDetail("nextFireTime", nextFireTime); // 自定义健康检查逻辑:示例为判断上次触发是否超出2倍调度间隔 if (previousFireTime != null && trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; long intervalSeconds = cronTrigger.getCronExpression().getExpressionSummary().getIntervalInSeconds(); if (ChronoUnit.SECONDS.between(previousFireTime, Instant.now()) > intervalSeconds * 2) { healthBuilder = Health.down().withDetail("reason", "Job未按预期执行,上次触发时间已超出2倍调度间隔"); } } } else { healthBuilder = Health.down().withDetail("reason", "未找到指定的触发器"); } } catch (SchedulerException e) { healthBuilder = Health.down(e).withDetail("reason", "获取Quartz触发器信息失败"); } return healthBuilder.build(); } }
3. 关于MeterRegistry无Quartz指标的说明
Spring Boot 2.6.7默认不会自动注册Quartz相关Metrics,需手动配置开启:
import io.micrometer.core.instrument.MeterRegistry; import org.springframework.boot.actuate.autoconfigure.metrics.QuartzMetricsAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class QuartzMetricsConfig { @Bean public QuartzMetricsAutoConfiguration.QuartzMetricsBinder quartzMetricsBinder(Scheduler scheduler, MeterRegistry meterRegistry) { return new QuartzMetricsAutoConfiguration.QuartzMetricsBinder(scheduler, meterRegistry); } }
开启后会生成quartz.triggers类计数指标(如触发次数、错过次数),但不包含previousFireTime和nextFireTime,因此仍推荐使用Scheduler API获取目标数据。
内容的提问来源于stack exchange,提问作者user3816621
相关产品推荐
相关产品推荐

