- : настраиваемые индикаторы HealthIndicator с большим количеством зависимостей, предоставляемые явно через свойство приложения
Код: Выделить всё
extended - : все, кроме определенных в расширенной группе
Код: Выделить всё
readiness
Код: Выделить всё
db
├ storeDataSource
└ pizzaDataSource
diskSpace
gracefulShutdownHealthCheck
hazelcast
jms
├ internalActiveMQConnectionFactory
├ notifConnectionFactory
└ platformJmsConnectionFactory
ping
refreshScope
Поэтому мы делаем следующее:
Код: Выделить всё
@Configuration
@AllArgsConstructor
public class HealthGroupMetricsConfig {
private final MeterRegistry meterRegistry;
private final HealthEndpoint healthEndpoint;
@PostConstruct
public void bindReadinessHealth() {
HealthComponent component = healthEndpoint.healthForPath("readiness");
CompositeHealth health = (CompositeHealth) component;
health.getComponents().forEach( (key, value) -> {
if (value instanceof Health h) {
Gauge.builder("app_health_readiness_component", h, he -> "UP".equalsIgnoreCase(h.getStatus().getCode()) ? 1 : 0)
.tag("component", key)
.register(meterRegistry);
} else if (value instanceof CompositeHealth ch) {
Gauge.builder("app_health_readiness_component", ch, he -> "UP".equalsIgnoreCase(ch.getStatus().getCode()) ? 1 : 0)
.tag("component", key)
.register(meterRegistry);
}
});
}
}
Если мы просто поместим healthForPath внутрь Gauge.builder, чтобы иметь новый вызов /actuator/health/readiness, то он будет вызываться несколько раз (столько, сколько компонентов у нас есть) без необходимости.
Наш второй подход заключался в том, чтобы вызвать healthForPath один раз в начале, чтобы просто собрать имена компонентов работоспособности, а затем внедрить их как bean-компонент из контекста приложения:
Код: Выделить всё
@Configuration
@AllArgsConstructor
public class HealthGroupMetricsConfig {
private final MeterRegistry meterRegistry;
private final HealthEndpoint healthEndpoint;
private final ApplicationContext applicationContext;
@PostConstruct
public void bindReadinessHealth() {
HealthComponent component = healthEndpoint.healthForPath("readiness");
CompositeHealth health = (CompositeHealth) component;
health.getComponents().keySet().forEach(name -> Gauge.builder("app_health_readiness_component", () -> {
HealthIndicator hi = applicationContext.getBean(name, HealthIndicator.class);
return hi.health().getStatus().equals(UP) ? 1 : 0;
})
.tag("component", name)
.register(meterRegistry));
}
}
Код: Выделить всё
gracefulShutdownHealthCheck
hazelcastHealthContributor
diskSpaceHealthIndicator
pingHealthContributor
refreshScopeHealthIndicator
Нашей последней мыслью было сделать вызов HTTP для каждого компонента, поскольку отдельные статусы можно оценить, вызвав /actuator/health/readiness/. Таким образом, мы можем достичь желаемой цели, но опасаемся некоторых проблем с производительностью из-за нескольких вызовов HTTP (если таковые имеются).
Есть предложения, как это сделать?
Мы используем Spring Boot версии 2.7.18.
Подробнее здесь: https://stackoverflow.com/questions/797 ... pring-boot
Мобильная версия