Monolit spája všetky funkcie aplikácie do jedného nasaditeľného celku. Kód síce môže obsahovať vrstvy, moduly a interné rozhrania, no release zvyčajne presúva aplikáciu ako kompletný celok. Rozhodujúcim znakom je práve táto hranica nasadenia (deployment boundary). Sama o sebe však nehovorí nič o tom, či je kód dobre štruktúrovaný alebo náročný na údržbu.
Čo robí systém monolitickým
Monolitické aplikácie udržiavajú beh aj nasadenie v rámci jednej aplikačnej hranice. Ich interné časti môžu volať jedna druhú priamo v pamäti, zdieľať knižnice a pristupovať k tej istej databáze. Tieto rozhodnutia znižujú potrebu sieťovej komunikácie medzi modulmi, zároveň však uľahčujú, aby jednotlivé hranice zostali iba implicitné.
| Dimenzia | Monolitická hranica | Otázka pri audite |
|---|---|---|
| Nasadenie (deployment) | Jeden release aplikácie | Ktoré zmeny sa musia vydať spoločne? |
| Dáta | Často jedno zdieľané úložisko | Ktorý modul vlastní jednotlivé záznamy? |
| Volania | Zvyčajne v rámci jedného procesu (in-process) | Ktoré volania prekračujú logické hranice? |
| Chyby a zlyhania | Zdieľaný behový čas (runtime) a zdroje | Ktorá chyba môže ovplyvniť nesúvisiace funkcie? |
Monolit môže mať aj napriek tomu jasné vlastníctvo modulov a stabilné rozhrania. Toto označenie opisuje spôsob, akým sa aplikácia balí a prevádzkuje, nie kvalitu jej návrhu.
Prečo sa legacy monolity začnú meniť len ťažko
Dlho prevádzkované aplikácie časom akumulujú prepojenia, ktoré v štruktúre priečinkov nevidno. Jedna funkcia tak môže čítať tabuľky inej funkcie, opätovne používať jej interné triedy alebo závisieť od udalosti, ktorá nebola nikdy zdokumentovaná. Drobná zmena potom môže vyžadovať kompletný release a overenie v zdanlivo nesúvisiacich oblastiach.
Audit legacy kódu (legacy codebase audit) mapuje tieto prepojenia pred tým, než tím pristúpi k zmene architektúry. Zameriava sa na:
- Vstupné body za behu aplikácie (runtime entry points). Webové požiadavky, plánované úlohy, fronty a administratívne operácie, ktoré spúšťajú prácu.
- Vlastníctvo dát (data ownership). Kód, ktorý vytvára, aktualizuje a interpretuje dôležité záznamy.
- Cesty zmien (change paths). Moduly, ktoré sa opakovane upravujú spoločne v rovnakých commitoch alebo releasoch.
- Prevádzkové hranice (operational boundaries). Procesy, zdroje a chybové stavy zdieľané naprieč funkciami.
Tieto zistenia odlišujú veľký, no usporiadaný monolit od takého, ktorého interné hranice už erodovali.
Ako sa dá monolit modernizovať
Modernizácia nevyžaduje okamžitú výmenu modelu nasadenia. Tím môže najskôr obnoviť interné hranice, presunúť zodpovednosť do modulov a zaviesť explicitné rozhrania. Týmto spôsobom môže vzniknúť modulárny monolit, pričom sa zachová jedna jednotka nasadenia (release unit).
Ak niektorá funkcia vyžaduje samostatný životný cyklus, vyčlenenie služby ju môže presunúť za sieťovú hranicu. Migrácia však musí stále brať do úvahy vlastníctvo dát, volajúcich, spracovanie chýb a poradie nasadzovania. Vyčlenenie kódu bez definovania týchto kontraktov môže preniesť existujúcu previazanosť kódu (code coupling) do distribuovaného systému.
Čo zaznamenáva migračný plán
Migračný plán by mal definovať súčasnú hranicu, cieľovú hranicu a fakty, ktoré túto zmenu umožňujú. Malo by v ňom byť taktiež uvedené, ktoré časti zostávajú v monolite počas každej fázy. Tým sa explicitne vyjasní ich koexistencia a poskytne sa stabilný súbor správaní, ktoré môžu chrániť testy aktuálneho správania (characterization test).
Výsledok auditu legacy kódu preto nie je automatickým pokynom na rozdelenie aplikácie. Je to mapa ukazujúca, ktoré hranice už fungujú, ktoré potrebujú opravu a ktoré funkcie sa môžu presunúť bez toho, aby sa narušilo správanie, od ktorého biznis stále závisí.