Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

MicroProfile Config и Health

MicroProfile — набор спецификаций для сервисов в облаке, который развивается рядом с Jakarta EE и опирается на CDI. Open Liberty поддерживает его полностью — мы включили microProfile-7.1 ещё в первом уроке. Разберём две самые нужные части: Config — настройки, которые можно менять без пересборки, и Health — адреса, по которым система развёртывания узнаёт, живо ли приложение.

Файл настроек

Генератор уже создал файл src/main/resources/META-INF/microprofile-config.properties. Запишите в него настройки блога:

# src/main/resources/META-INF/microprofile-config.properties
blog.title=Блог Анны
blog.page-size=10

Внедрение настроек

// src/main/java/com/example/blog/SettingsResource.java
package com.example.blog;
 
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.Optional;
import org.eclipse.microprofile.config.inject.ConfigProperty;
 
@Path("/settings")
@Produces(MediaType.APPLICATION_JSON)
public class SettingsResource {
 
    public record Settings(String title, int pageSize, String banner) {
    }
 
    @Inject
    @ConfigProperty(name = "blog.title")
    String title;
 
    @Inject
    @ConfigProperty(name = "blog.page-size", defaultValue = "20")
    int pageSize;
 
    @Inject
    @ConfigProperty(name = "blog.banner")
    Optional<String> banner;
 
    @GET
    public Settings settings() {
        return new Settings(title, pageSize, banner.orElse("нет"));
    }
}

defaultValue используется, если настройки нигде нет, а Optional подходит для необязательных значений. Строка превращается в int сама.

curl http://localhost:8080/blog/api/settings
{"banner":"нет","pageSize":10,"title":"Блог Анны"}

Источники и приоритет

ИсточникПримерПриоритет
Системные свойства Java-Dblog.page-size=5Самый высокий
Переменные окруженияBLOG_PAGE_SIZE=5Средний
microprofile-config.propertiesblog.page-size=10Самый низкий

Для переменной окружения точки и дефисы заменяются на _, а буквы становятся заглавными. Запустим сервер с переменными:

BLOG_PAGE_SIZE=5 BLOG_BANNER="Осенняя распродажа" ./mvnw liberty:dev
{"banner":"Осенняя распродажа","pageSize":5,"title":"Блог Анны"}

Так одна и та же сборка работает с разными настройками на ноутбуке и на сервере.

Проверки состояния

Системы развёртывания вроде Kubernetes регулярно спрашивают приложение: живо ли оно (liveness) и готово ли принимать запросы (readiness). Проверка готовности для блога — доступна ли база:

// src/main/java/com/example/blog/DatabaseHealthCheck.java
package com.example.blog;
 
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Readiness;
 
@Readiness
@ApplicationScoped
public class DatabaseHealthCheck implements HealthCheck {
 
    @Inject
    PostRepository repository;
 
    @Override
    public HealthCheckResponse call() {
        try {
            long posts = repository.count();
            return HealthCheckResponse.named("database")
                    .up()
                    .withData("posts", posts)
                    .build();
        } catch (RuntimeException e) {
            return HealthCheckResponse.named("database")
                    .down()
                    .withData("error", e.getMessage())
                    .build();
        }
    }
}

И простая проверка «живо»:

// src/main/java/com/example/blog/AliveCheck.java
package com.example.blog;
 
import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Liveness;
 
@Liveness
@ApplicationScoped
public class AliveCheck implements HealthCheck {
 
    @Override
    public HealthCheckResponse call() {
        return HealthCheckResponse.up("blog");
    }
}

Адреса проверок принадлежат серверу, а не приложению, поэтому в них нет /blog:

curl http://localhost:8080/health/ready
curl http://localhost:8080/health
{"status":"UP","checks":[{"name":"database","status":"UP","data":{"posts":2}}]}
{"status":"UP","checks":[{"name":"blog","status":"UP","data":{}},{"name":"database","status":"UP","data":{"posts":2}}]}
АдресКакие проверки
/health/live@Liveness
/health/ready@Readiness
/health/started@Startup
/healthВсе сразу

Если хоть одна проверка вернёт down(), общий статус станет DOWN, а код ответа — 503.

Частая ошибка

Внедрить обязательную настройку, которой нет ни в одном источнике. Приложение не запустится:

SRCFG02000: Failed to Inject @ConfigProperty for key blog.owner into com.example.blog.SettingsResource.title since the config property could not be found in any config source

Добавьте значение в файл настроек, задайте defaultValue или сделайте поле Optional.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.