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.properties | blog.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.