Как я могу контролировать порядок завершения работы компонентов, управляемых Spring, которые я не создаю сам?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как я могу контролировать порядок завершения работы компонентов, управляемых Spring, которые я не создаю сам?

Сообщение Anonymous »

У меня есть приложение Spring Boot, работающее в Kubernetes. Я пытаюсь реализовать поток мягкого завершения работы с помощью проверки готовности:
  • Приложение получает SIGTERM.
  • Приложение должно начать возвращать 503 из /health, чтобы Kubernetes прекратил отправлять новый трафик.
  • Существующие запросы завершаются.
  • Приложение закрывается.
Я хотел бы записать показатели последних нескольких вызовов /health (особенно ответов 503 во время завершения работы) с помощью MeterRegistry компании Micrometer. Однако я вижу, что MeterRegistry уже закрыт, а проверка готовности все еще обращается к /health.
Соответствующая конфигурация k8s:

Код: Выделить всё

readinessProbe:
initialDelaySeconds: 30
periodSeconds: 1
failureThreshold: 1
httpGet:
path: /health
port: 9091
Контроллер:

Код: Выделить всё

import io.micrometer.core.instrument.MeterRegistry;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import static org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE;

@RestController
@RequiredArgsConstructor
@Slf4j
public class HealthController {
private final StatusService statusService;
private final MeterRegistry meterRegistry;

@GetMapping("/health")
public ResponseEntity health() {
Status status = statusService.status();
ResponseEntity response = status == Status.OK
? ResponseEntity.ok(status.name())
: ResponseEntity.status(SERVICE_UNAVAILABLE).body(status.name());

int statusCode = response.getStatusCode().value();
String statusCodeString = String.valueOf(statusCode);
meterRegistry.counter("health_check_status", "code", statusCodeString).increment();

log.debug("Health check returned: {}. Status code: {}. meterRegistry.isClosed(): {}",
response, statusCodeString, meterRegistry.isClosed());
return response;
}
}
Журналы завершения работы:

Код: Выделить всё

2025-12-08 13:15:24.096  Health check returned: . Status code: 200. meterRegistry.isClosed(): false
2025-12-08 13:15:25.092  Health check returned: . Status code: 200. meterRegistry.isClosed(): false
2025-12-08 13:15:26.092  Health check returned: . Status code: 503. meterRegistry.isClosed(): true
2025-12-08 13:15:26.095  Health check returned: . Status code: 503. meterRegistry.isClosed(): true
Поэтому, когда мой StatusService сообщает SHUTTING_DOWN и /health начинает возвращать 503,meterRegistry.isClosed() уже имеет значение true, что означает, что я не могу надежно записать эти 503 показатели.
Из того, что я вижу:
  • Код: Выделить всё

    MeterRegistry
    создается и управляется посредством автоматической настройки Spring Boot.
  • При SIGTERM Spring Boot завершает работу и в конечном итоге вызывает MeterRegistry#close().
  • Я не управляю компонентом реестра напрямую (нет определения пользовательского компонента, нет @DependsOn и т. д.).
Вопросы
  • Есть ли в Spring Boot способ отложить или настроить вызов MeterRegistry.close() во время завершения работы, чтобы я мог записывать метрики во время последних вызовов проверки готовности?
  • Если нет, то какой шаблон рекомендуется использовать? чтобы:
    • поддерживать /health отвечать с точным статусом во время завершения работы и
    • по-прежнему записывать метрики для этих ответов, когда MeterRegistry управляется Spring Boot?


Подробнее здесь: https://stackoverflow.com/questions/798 ... n-t-create
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»