QuarkusSeniorExperience

Какие production-риски есть у Quarkus: blocking code, connection pooling, config, auth, observability, deploy или graceful shutdown?

Ключевые production-риски Quarkus: блокирующий код на event-loop-потоке, исчерпание пула соединений Agroal/Vert.x, неправильная конфигурация профилей, проблемы с OIDC/JWT при ротации ключей, отсутствие structured logging и медленный graceful shutdown при долгих задачах.

Production-риски Quarkus

Quarkus строится поверх Vert.x event loop. Нарушение его контракта или неверная настройка инфраструктурных компонентов приводит к незаметным деградациям в production.

1. Blocking code на event-loop потоке

Методы CDI-бинов по умолчанию выполняются на IO-потоке Vert.x. Вызов блокирующей JDBC или Thread.sleep там блокирует весь event loop.

// НЕПРАВИЛЬНО — блокирует event loop
@GET
@Path("/slow")
public String slow() throws Exception {
    Thread.sleep(2000); // заблокирует весь поток!
    return "done";
}

// ПРАВИЛЬНО — аннотация переносит выполнение на worker pool
@GET
@Path("/slow")
@Blocking
public String slow() throws Exception {
    Thread.sleep(2000);
    return "done";
}

Диагностика: quarkus.vertx.max-event-loop-execute-time=2S — Quarkus залогирует предупреждение при превышении.

2. Connection pooling

Agroal (JDBC) и реактивный PgPool имеют разные пулы. Типичная ошибка — оставить значения по умолчанию.

# Agroal (блокирующий JDBC)
quarkus.datasource.jdbc.max-size=20
quarkus.datasource.jdbc.min-size=5
quarkus.datasource.jdbc.acquisition-timeout=10

# Реактивный клиент
quarkus.datasource.reactive.max-size=20
quarkus.datasource.reactive.idle-timeout=PT10M

Redis-клиент (Quarkus Redis) имеет отдельный пул: quarkus.redis.max-pool-size.

3. Конфигурация и профили

Секреты не должны попадать в образ. Используйте Kubernetes Secrets или Vault:

# application.properties — референс на env var
quarkus.datasource.password=${DB_PASSWORD}

# Профили: %prod, %dev, %test
%prod.quarkus.log.level=WARN
%dev.quarkus.log.level=DEBUG

Риск: при нативной сборке @ConfigProperty с defaultValue встраивается в бинарник — изменить без пересборки нельзя.

4. Auth и OIDC

quarkus.oidc.auth-server-url=https://keycloak/realms/prod
quarkus.oidc.token.refresh-expired=true
quarkus.oidc.token.lifespan-grace=60S
# Rotation публичного ключа
quarkus.oidc.jwks-path=/protocol/openid-connect/certs
quarkus.oidc.token-cache.max-size=1000

Риск: при ротации ключей Keycloak без token-cache каждый запрос идёт за JWKS — 401 burst при перезапуске Keycloak.

5. Observability

quarkus.micrometer.export.prometheus.enabled=true
quarkus.log.console.json=true
quarkus.log.console.json.additional-field.service.value=payment-api
quarkus.otel.exporter.otlp.endpoint=http://otel-collector:4317

Без structured logging трейсинг в ELK/Loki невозможен. OpenTelemetry-трейсы автоматически инструментируют RESTEasy, Hibernate, Kafka.

6. Graceful shutdown

quarkus.shutdown.timeout=30S
# Для Kafka consumer
quarkus.messaging.kafka.graceful-shutdown-timeout=15000

В Kubernetes добавьте preStop hook, чтобы дать LB время убрать pod из ротации до начала shutdown.

Подводные камни

  • @Transactional на реактивном пути — стандартный @Transactional не работает с Panache Reactive; нужен @WithTransaction или Panache.withTransaction().
  • Native image и reflection — динамический Class.forName() без регистрации в @RegisterForReflection падает в prod native-бинаре, но работает в JVM dev-режиме.
  • Kafka consumer lag — по умолчанию Quarkus Kafka читает с latest; при деплое новых инстанций без earliest теряются сообщения.
  • Dev Services в CIquarkus.devservices.enabled=false обязательно в test/prod профилях, иначе Testcontainers запустится в production-контейнере.
  • quarkus.http.idle-timeout по умолчанию 30 минут — AWS NLB/ALB разрывают TCP через 350 с, что приводит к silent connection drops.
  • Memory в native — RSS native-бинаря растёт под нагрузкой из-за JIT-аналога (GraalVM AOT не компенсирует heap полностью); настраивайте -Xmx эквивалент через -R:MaxHeapSize.

What hurts your answer

  • Говорить только о запуске Quarkus, но не об эксплуатации
  • Не упоминать observability, обновления, безопасность и rollback
  • Описывать риски абстрактно, без способов их снижать

What they're listening for

  • Видит production-риски Quarkus
  • Говорит про monitoring, rollout, rollback и безопасность
  • Умеет ранжировать риски по вероятности и влиянию

Related topics