Správa konfigurace aplikace: 10 typických chyb v produkčním prostředí
Nesprávné časové limity, tajné klíče nebo omezení v konfiguraci způsobují výpadky rychleji než chyby v logice kódu. Na rozdíl od kódu konfigurace často vyhne code review, testům i CI procesům. To vytváří vážná rizika: služba zapisuje do špatné databáze, vyčerpává fond připojení nebo unikají citlivé údaje. Analýza reálných projektů odhalila 10 chyb, které se maskují až do vzniku incidentu.
Hardcodované časové limity: 30+ míst v kódu
Časové limity přímo v zdrojovém kódu vyžadují novou sestavu pro každou změnu. Hledání výrazu Duration.ofSeconds odhalilo více než 30 případů s různými hodnotami: 10 s ve službě NotificationService, 30 s ve službě SearchService, 15 s v ApiRoutes.
private static final Duration TIMEOUT = Duration.ofSeconds(10); // NotificationService
private static final Duration TIMEOUT = Duration.ofSeconds(30); // SearchService
private static final Duration TIMEOUT = Duration.ofSeconds(10); // AuthFilter
private static final Duration TIMEOUT = Duration.ofSeconds(15); // ApiRoutes
Při zátěži je nastavení časových limitů kritické, ale hardcoding znemožňuje jejich dynamickou úpravu. Řešení: přesunout do konfigurace s možností přepsání prostředím (env-override).
Chybějící validace: smazání produkční databáze
Konfigurační objekt o 695 řádcích ověřuje pouze jeden parametr. Všechny ostatní jsou přijímány bez kontroly: fond připojení = 0, časový limit = −1, prázdná URL adresa databáze.
String authType = config.getString("authType");
if (!Set.of("kerberos", "jwt").contains(authType)) {
throw new IllegalArgumentException("Invalid auth type, possible values are kerberos, jwt");
}
Nebezpečný příklad: http.server.parsing.max-content-length = 10g — jeden požadavek spotřebuje 10 GB RAM. Parametr dropAll = ${?DROP_ALL} pro Liquibase smaže celou schému bez potvrzení. Fail-fast při spuštění aplikace zabrání incidentům.
Výchozí hodnoty skrývají problémy
Výchozí hodnoty skrývají chybějící klíče až do běhu aplikace. Při zapnutí SSO:
Duration maxResponseDelay = ssoEnabled
? config.getDuration("sso.maxResponseDelay")
: Duration.ofMinutes(10);
long responseCacheSize = ssoEnabled
? config.getLong("sso.responseCacheSize")
: 10_000;
Klíče neexistují — aplikace selže v produkci. Stejně tak u tokenTtl: konfigurace „1 minuta“ se tiše změní na „3 minuty“ bez záznamu v logu, což porušuje bezpečnostní požadavky.
- Problém výchozích hodnot: skrývají nesprávnou konfiguraci až do aktivace funkce.
- Řešení: validace při startu, varování při použití fallbacku.
Rozdíly mezi konfiguracemi test/prod
Testovací konfigurace se od produkční liší řádově:
| Parametr | Produkce | Test |
|----------|----------|------|
| api.responseLimit | 10 MB | 1 GB |
| api.contextLimit | 10 MB | 1 MB |
Odpověď o velikosti 50 MB projde testem, ale v produkci selže. Opačný scénář: testy jsou příliš přísné → falešně negativní výsledek.
Chaos v pojmenování parametrů
Jeden soubor application.conf kombinuje různé styly:
fileStoragePath = "/opt/storage" # camelCase
retention-days = 7 # kebab-case
createdump-interval-seconds = 240 # hybrid
usage-threshold = 80 # kebab-case
compressHeapDump = true # camelCase
Logické hodnoty: sslValidationEnabled, smtpSslEnable, saml.enabled, isUseSecureCookieJWT. Přepsání prostředím nefunguje: smtpSslEnable → SMTP_SSL_ENABLED („Enable“ vs „Enabled“).
- Kombinace camelCase a kebab-case v jednom souboru.
- Nesoulad mezi HOCON a proměnnými prostředí.
- Čtyři různé konvence pojmenování logických příznaků.
Zombie feature flagy bez životního cyklu
16 příznaků v třídě Config: ws-cache-enabled=false všude, history-import-enabled=true vždy. Chybí data, autoři, důvody — kognitivní zátěž roste.
- Přidat: datum, autor, důvod, termín odstranění.
- Odstranit „nesmrtelné“ příznaky: vždy
true/false, nepoužívané.
Nesprávné pořadí přepisování v HOCON
V HOCON platí: poslední hodnota přepíše předchozí. Správně:
key = "default-value"
key = ${?ENV_OVERRIDE}
Chybně:
dump {
enabled = ${?DUMP_ENABLED}
enabled = false
directory = ${?DUMP_DIR}
directory = "opt/myapp/dumps/auto"
}
Proměnná prostředí je přepsána hodnotou false — automatické vytváření dumpů se nezapne.
Konfigurace bez dokumentace: 100+ parametrů
Soubor docker.md uvádí proměnné prostředí bez popisu: EMAIL_ENABLED=false/true. AppConfig.java má 695 řádků bez Javadocu. sync-request-timeout-seconds=600 — pro co? workflowStepLimit=200 — jaké jsou důsledky při hodnotách 0 nebo 100 000?
Hardcodované externí URL a úroveň logování
URL adresy API v kódu vyžadují novou sestavu při změně koncového bodu. Úroveň logování v Docker obrazu vyžaduje buď volume mount, nebo novou sestavu pro DEBUG.
Co je klíčové:
- Veškerou konfiguraci přesunout do externího souboru s validací při startu.
- Používat jednotný styl pojmenování pro HOCON i proměnné prostředí.
- Dokumentovat každý parametr: datový typ, povolený rozsah, výchozí hodnota, účel.
- Preferovat fail-fast před tišením chyb.
- Zavést životní cyklus pro feature flagy: datum, důvod a termín odstranění.
— Editorial Team
Zatím žádné komentáře.