Poglavlje 9: Arhitektura sistema
Priča za početak. U avgustu 2008. godine firma Netflix još nije bila poznata po filmovima na internetu. Njen glavni posao bio je slanje DVD diskova poštom: kupac na stranici izabere film, a Netflix mu pošalje disk u koverti. Tada se desila nezgoda: pokvarila se velika baza podataka u njihovom računskom centru. Tri dana Netflix nije mogao slati DVD-ove svojim članovima. Sve je zavisilo od jednog velikog računara i jedne baze, i kad je ona stala, stao je cijeli posao. Inženjeri su izvukli pouku koja je promijenila firmu: sistem se ne smije oslanjati na jednu tačku koja, kad otkaže, obori sve. Odlučili su da sistem rastave na mnogo manjih dijelova koji rade nezavisno i da ga presele u oblak, kod Amazona, gdje se dijelovi mogu umnožiti po potrebi. Prelazak je trajao sedam godina i završen je u januaru 2016. godine. Netflix je danas jedan od najpoznatijih primjera kako odluke o arhitekturi, a ne o boji dugmadi, odlučuju da li sistem preživi lošu noć.
U poglavljima 4 do 8 opisali smo šta DeliveryApp radi i šta zna: procese, slučajeve korištenja, klase, stanja i bazu. Sada pitamo: od kojih dijelova se DeliveryApp sastoji, gdje ti dijelovi rade i kako razgovaraju? To je arhitektura. Poglavlje počinje objašnjenjem šta je arhitektura i kako je slojevi čine razumljivom, i kako nefunkcionalni zahtjevi iz poglavlja 3 (200 korisnika, 99,5 % dostupnosti) odlučuju o njoj. Zatim upoređujemo monolit i mikroservise, upoznajemo oblak i skaliranje. Na kraju crtamo arhitekturu DeliveryApp C4 modelom i zapisujemo arhitektonske odluke. Na praktičnoj nastavi crtamo C4 dijagrame, računamo dostupnost i pišemo dvije odluke (ADR).
Literatura. Osnovna literatura predmeta:
- B. Popović, K. Kuk: Informacioni sistemi, Kriminalističko-policijski univerzitet, Beograd, 2017.
- J. S. Valacich, J. F. George: Modern Systems Analysis and Design, 9th ed., Pearson, 2020.
- L. Jelenković: Sustavi za rad u stvarnom vremenu – skripta, FER, Zagreb, 2015.
- D. Milićev: Programiranje u realnom vremenu – skripta, Beograd, 2002.
- V. Kovačević, M. Popović: Sistemska programska podrška u realnom vremenu 1, FTN, Novi Sad, 2013.
Riječi ovog poglavlja.
- Arhitektura softvera – najvažnije odluke o dijelovima sistema i njihovim vezama, koje se kasnije teško mijenjaju.
- Sloj – grupa dijelova sistema s jednim zadatkom (prikaz, pravila, podaci); svaki sloj razgovara samo sa susjednim.
- Klijent i server – klijent (aplikacija na mobitelu) traži, server (računar u centru) odgovara.
- Monolit – sistem napravljen i pušten kao jedan program.
- Mikroservisi – sistem od mnogo malih, samostalnih programa koji razgovaraju preko mreže.
- Oblak (cloud) – računari, prostor i usluge koje se iznajmljuju preko interneta i plaćaju po potrošnji.
- IaaS, PaaS, SaaS – iznajmljivanje infrastrukture, platforme ili gotove aplikacije.
- Skaliranje – povećanje kapaciteta: jači računar (vertikalno) ili više računara (horizontalno).
- Balanser opterećenja – program koji raspoređuje zahtjeve na više servera.
- Keš (cache) – brza memorija s kopijom često traženih podataka.
- Jedinstvena tačka otkaza – dio sistema čiji kvar obori cijeli sistem.
- Redundancija – dodatni primjerak dijela sistema koji preuzima posao kad prvi otkaže.
- C4 model – četiri nivoa crteža arhitekture: kontekst, kontejneri, komponente, kod.
- ADR (architecture decision record) – kratak zapis jedne arhitektonske odluke: kontekst, odluka, posljedice.
Ciljevi poglavlja. Nakon poglavlja možete: objasniti šta je arhitektura i po čemu se razlikuje od detaljnog dizajna; opisati troslojnu arhitekturu i reći zašto pravila DeliveryApp žive na serveru; izračunati dostupnost dva dijela u nizu i dva paralelna dijela; pokazati kako redundancija ispunjava NZ-2; uporediti monolit i mikroservise i obrazložiti izbor za DeliveryApp; razlikovati IaaS, PaaS i SaaS; procijeniti broj zahtjeva u sekundi za 200 korisnika; razlikovati vertikalno i horizontalno skaliranje i objasniti balanser i keš; nacrtati C4 dijagram konteksta i kontejnera; napisati arhitektonsku odluku u obliku ADR.
Plan poglavlja – Sedmica 9: tri časa teorije i tri časa praktične nastave
| Čas | Sadržaj | Na času |
|---|---|---|
| Teorija 1 | 9.1–9.3 Šta je arhitektura; slojevi; zahtjevi pokreću arhitekturu | 99,5 % · 99,5 % = 99,0 %; redundancija |
| Teorija 2 | 9.4–9.6 Monolit i mikroservisi; oblak; skaliranje | Pizza kao usluga; 40 zahtjeva u sekundi |
| Teorija 3 | 9.7–9.9 C4 model; kontejneri DeliveryApp; ADR | ADR-001: modularni monolit |
| Praksa 1–3 | C4 u Mermaidu; račun dostupnosti; dva ADR-a | arhitektura.md |
Dio 1 – Šta je arhitektura
9.1 Odluke koje se teško mijenjaju
Ima mnogo definicija arhitekture softvera, ali jedna je najkorisnija: arhitektura su one odluke koje se kasnije teško mijenjaju. Boja dugmeta „Naruči” mijenja se za pet minuta. Odluka da aplikacija i server razgovaraju preko interneta, da se podaci čuvaju u relacionoj bazi ili da je sistem jedan program, a ne pedeset malih, mijenja se mjesecima.
Slika iz života je ponovo kuća. Raspored namještaja nije arhitektura: može se promijeniti za jedno popodne. Noseći zidovi, mjesto stepeništa, debljina temelja i gdje idu cijevi jesu arhitektura: ako se kasnije pokaže da su pogrešni, popravka znači rušenje. Arhitekta zato o nosećim zidovima razmišlja najviše, a o namještaju najmanje.
Za DeliveryApp su arhitektonske odluke na primjer:
- gdje se računa cijena: u aplikaciji na mobitelu ili na serveru;
- koliko servera radi i šta se dešava kad jedan otkaže;
- koja baza čuva podatke i gdje;
- da li je server jedan program ili više samostalnih servisa;
- kako aplikacija saznaje da je narudžba promijenila stanje (pita svakih 10 sekundi ili joj server javlja).
Arhitektura se ne crta jednom za sva vremena, ali se najvažnije odluke donose rano, jer na njima stoji sve ostalo. A kad se donesu, zapisuju se zajedno s razlogom (9.9), da bi i za dvije godine bilo jasno zašto je tako.
Ukratko.
- Arhitektura su odluke o dijelovima sistema i njihovim vezama koje se kasnije teško mijenjaju.
- Kao noseći zidovi kuće, za razliku od namještaja.
- Za DeliveryApp to su: gdje se računa cijena, koliko servera, koja baza, monolit ili servisi, kako se javljaju promjene.
- Najvažnije odluke donose se rano i zapisuju se s razlogom.
9.2 Slojevi i klijent–server
Najstariji i najkorisniji način da se arhitektura učini razumljivom je podjela na slojeve. Svaki sloj ima jedan zadatak i razgovara samo sa susjednim slojem:
- Sloj prikaza (presentation) – ono što korisnik vidi i dodiruje: ekrani mobilne aplikacije i web stranica restorana. Ovaj sloj ne zna pravila; samo ih prikazuje.
- Sloj poslovne logike (business logic) – pravila PP-1 do PP-6, mašina stanja narudžbe, obračun cijene. Ovdje žive klase iz poglavlja 6 i 7.
- Sloj podataka (data) – baza iz poglavlja 8 i kod koji s njom razgovara.
DeliveryApp je raspoređen kao klijent–server: klijent (aplikacija na mobitelu kupca, ekran u kuhinji) šalje zahtjev preko interneta, a server (računar u računskom centru ili oblaku) ga obradi i vrati odgovor. Sloj prikaza je na klijentu, a slojevi logike i podataka na serveru. Takav raspored zove se troslojna arhitektura.
Zašto se pravila ne programiraju u aplikaciju na mobitelu, gdje bi bila brža? Tri razloga:
- Jedno mjesto istine. Kad udruženje promijeni PP-2, promijeni se jedan server, a ne hiljade aplikacija na mobitelima, od kojih neke kupci nikad ne ažuriraju.
- Sigurnost. Kod na mobitelu kupca može se izmijeniti. Kad bi aplikacija sama računala cijenu, vješt korisnik bi mogao poslati „ukupno 0,50 €”. Server zato uvijek sam ponovo izračuna cijenu i ne vjeruje broju koji je poslao klijent.
- Više klijenata. Isti server služi mobilnu aplikaciju, web stranicu restorana i aplikaciju dostavljača.
Slika iz života: restoran. Gost (klijent) razgovara samo s konobarom (sloj prikaza). Konobar odnese narudžbu u kuhinju (poslovna logika), gdje kuhar zna recepte. Kuhar uzima namirnice iz ostave (podaci). Gost ne ulazi u ostavu, a konobar ne kuha.

Ukratko.
- Troslojna arhitektura dijeli sistem na sloj prikaza, sloj poslovne logike i sloj podataka.
- Klijent (mobitel, ekran u kuhinji) šalje zahtjeve, a server ih obrađuje.
- Pravila DeliveryApp žive na serveru: jedno mjesto istine, sigurnost i više klijenata.
- Server nikad ne vjeruje cijeni koju je poslao klijent, nego je sam izračuna.
9.3 Nefunkcionalni zahtjevi pokreću arhitekturu
Funkcionalni zahtjevi (šta sistem radi) rijetko odlučuju o arhitekturi: obračun dostave može se napisati u bilo kojoj arhitekturi. O arhitekturi odlučuju nefunkcionalni zahtjevi iz poglavlja 3: koliko korisnika, koliko brzo, koliko dostupno, koliko sigurno.
Uzmimo NZ-2: dostupnost 99,5 % mjesečno, odnosno najviše 3,6 sati zastoja u 30 dana. Pretpostavimo da i server i baza, svaki za sebe, rade 99,5 % vremena.
Dijelovi u nizu
Ako sistem radi samo kad rade i server i baza (dijelovi u nizu), njihove dostupnosti se množe:
\[ A_{\text{niz}} = A_1 \times A_2 = 0{,}995 \times 0{,}995 \approx 0{,}990 \]
Čemu služi. Formula pokazuje da je sistem od dva dijela u nizu slabiji od svakog dijela posebno: dostupnost pada na oko 99,0 %, a to je oko 7,2 sata zastoja mjesečno, duplo više nego što NZ-2 dozvoljava. Svaki novi dio u nizu (red poruka, servis mapa) dodatno smanjuje dostupnost. Dio čiji kvar obori cijeli sistem zove se jedinstvena tačka otkaza; u Netflixovoj priči to je bila baza.
Dijelovi paralelno (redundancija)
Ako postoje dva servera i sistem radi dok radi bar jedan (dijelovi paralelno), sistem otkaže samo kad otkažu oba istovremeno. Vjerovatnoća da jedan ne radi je 1 − 0,995 = 0,005, da oba ne rade 0,005 × 0,005 = 0,000025:
\[ A_{\text{paralelno}} = 1 - (1 - A)^2 = 1 - 0{,}005^2 = 0{,}999975 \]
Čemu služi. Dva servera od kojih je svaki dostupan 99,5 % daju zajedno 99,9975 %. To je redundancija: dodatni primjerak koji preuzima posao. Ali pažnja: ako su dva servera paralelno, a baza je i dalje jedna, cijeli sistem je u nizu „par servera × baza”: 0,999975 × 0,995 ≈ 0,99497, odnosno oko 99,50 %, s oko 3,6 sati zastoja mjesečno, tačno na granici NZ-2 (preciznije 3,62 sata, malo preko). Baza je ostala jedinstvena tačka otkaza. Tek kad i baza ima rezervnu kopiju (repliku) koja preuzima posao, sistem dolazi na oko 99,995 %, a to su oko 2 minute zastoja mjesečno.
| Raspored | Dostupnost | Zastoj u 30 dana |
|---|---|---|
| jedan server + jedna baza (niz) | ≈ 99,0 % | ≈ 7,2 h |
| dva servera + jedna baza | ≈ 99,50 % | ≈ 3,6 h |
| dva servera + baza s replikom | ≈ 99,995 % | ≈ 2 min |
Pretpostavka ovih računa je da kvarovi dolaze nezavisno. Ako oba servera stoje u istoj sobi i nestane struje, otkažu zajedno, i redundancija ne pomaže. Zato se rezervni primjerci stavljaju na različita mjesta (druga zgrada, druga „zona” u oblaku).
Broj za pamćenje. Dva dijela u nizu od po 99,5 % daju samo 99,0 %; dva paralelna daju 99,9975 %. Niz slabi, paralela jača.

Ukratko.
- O arhitekturi najčešće odlučuju nefunkcionalni zahtjevi: broj korisnika, brzina, dostupnost, sigurnost.
- Dijelovi u nizu množe dostupnosti: 0,995 × 0,995 ≈ 99,0 %, oko 7,2 sata zastoja mjesečno.
- Paralelni dijelovi otkazuju samo zajedno: 1 − 0,005² = 99,9975 %.
- Dok je baza jedna, ona je jedinstvena tačka otkaza; tek replika baze daje oko 2 minute zastoja mjesečno.
Provjeri se.
- Je li raspored namještaja u kući arhitektura? – Ne; arhitektura su noseći zidovi, odluke koje se teško mijenjaju.
- Zašto server ponovo računa cijenu koju je poslala aplikacija? – Jer se kod na mobitelu može izmijeniti, pa server ne vjeruje klijentu.
- Kolika je dostupnost dva dijela u nizu od po 99,5 %? – Oko 99,0 %.
Dio 2 – Stilovi, oblak i skaliranje
9.4 Monolit i mikroservisi
Server DeliveryApp može se napraviti na dva bitno različita načina.
Monolit je jedan program koji sadrži sve: jelovnik, narudžbe, plaćanje, dostavu, izvještaje. Pravi se, testira i pušta u rad kao jedna cjelina. Mikroservisi su mnogo malih programa, svaki za jedan posao (servis narudžbi, servis plaćanja, servis dostave), koji rade nezavisno i razgovaraju preko mreže.
| Monolit | Mikroservisi | |
|---|---|---|
| Početak | brz i jednostavan | sporiji: treba postaviti mnogo dijelova |
| Puštanje u rad | sve odjednom | svaki servis zasebno |
| Skaliranje | umnožava se cijeli program | umnožava se samo servis kojem treba |
| Kvar jednog dijela | može oboriti sve | ostali servisi rade dalje |
| Poziv između dijelova | običan poziv funkcije, brz | poziv preko mreže, sporiji i može pasti |
| Tim | dobar za jedan mali tim | dobar za više timova koji rade nezavisno |
| Testiranje i praćenje grešaka | jednostavnije | složenije: greška putuje kroz više servisa |
Slika iz života: monolit je švicarski nož, sve u jednom, praktičan dok je mali. Mikroservisi su kutija s alatom: svaki alat je poseban, lako se zamijeni jedan, ali treba više mjesta i reda.
Mikroservisi su postali popularni zahvaljujući firmama kao što je Netflix, koje imaju stotine timova i milione korisnika. Ali za mali tim oni donose više posla nego koristi. Zato se za DeliveryApp predlaže treći put: modularni monolit. To je jedan program, ali podijeljen na jasne module (jelovnik, narudžbe, plaćanje, dostava) koji razgovaraju samo preko dogovorenih funkcija, kao da su posebni servisi. Ako jednom modul „dostava” zatreba nezavisnost, može se izdvojiti u servis bez prepisivanja svega.
Česta zabluda. „Mikroservisi su moderniji, pa su bolji.” Arhitektura nije moda. Mikroservisi rješavaju problem mnogo timova i ogromnog opterećenja; ako tih problema nema, oni samo dodaju mrežu, kašnjenje i složenost. Mnoge firme su se, nakon iskustva, s mikroservisa vratile na manji broj većih servisa.
Ukratko.
- Monolit je jedan program koji sadrži sve; mikroservisi su mnogo malih nezavisnih programa koji razgovaraju preko mreže.
- Monolit je jednostavniji za početak i mali tim; mikroservisi se nezavisno skaliraju i puštaju, ali su složeniji.
- Za DeliveryApp se predlaže modularni monolit: jedan program s jasnim modulima koji se kasnije mogu izdvojiti.
- Arhitektura nije moda: bira se prema stvarnim problemima.
9.5 Oblak
Server DeliveryApp negdje mora raditi. Nekad je firma kupovala računare, stavljala ih u svoju sobu s klima-uređajem i brinula o struji, mreži i rezervnim dijelovima. Danas se češće iznajmljuje u oblaku (cloud): veliki pružaoci (Amazon Web Services, Microsoft Azure, Google Cloud i drugi) imaju ogromne računske centre i iznajmljuju računare, prostor i usluge preko interneta, uz plaćanje po potrošnji.
Oblak se iznajmljuje na tri nivoa, a razliku je najlakše vidjeti na pizzi:
| Model | Šta iznajmljujete | Pizza kao usluga | Primjer za DeliveryApp |
|---|---|---|---|
| Sve svoje (on-premises) | ništa | pravite pizzu kod kuće: tijesto, pećnica, sto | svoj server u podrumu udruženja |
| IaaS (infrastruktura kao usluga) | virtuelne računare, mrežu, diskove | kupite gotovo tijesto, ali pečete u svojoj pećnici | iznajmljen virtuelni server, sami instaliramo sve |
| PaaS (platforma kao usluga) | gotovu platformu za pokretanje programa | naručite pizzu, a jedete za svojim stolom | pošaljemo kod, platforma ga pokreće i skalira; baza kao usluga |
| SaaS (softver kao usluga) | gotovu aplikaciju | večerate u piceriji | e-pošta, kalendar, sistem plaćanja |
Što se više iznajmljuje, to je manje briga, ali i manje kontrole i obično veća cijena po jedinici. Za mali tim DeliveryApp razuman izbor je PaaS za server i bazu kao uslugu (npr. upravljani PostgreSQL), jer pružalac sam pravi kopije, ažurira i drži repliku baze, a to je upravo ono što nam treba za NZ-2.
Oblak ima i rizike koje arhitekta mora navesti: mjesečni račun raste s potrošnjom; podaci kupaca su na tuđem računaru, pa se mora znati u kojoj zemlji (poglavlje 12); a prelazak kod drugog pružaoca može biti težak ako se koriste njegove posebne usluge (zaključavanje kod dobavljača, engleski vendor lock-in).
Ukratko.
- Oblak je iznajmljivanje računara, prostora i usluga preko interneta, uz plaćanje po potrošnji.
- IaaS iznajmljuje infrastrukturu, PaaS platformu za pokretanje programa, a SaaS gotovu aplikaciju.
- Za DeliveryApp je razuman izbor PaaS i baza kao usluga, jer pružalac drži kopije i repliku.
- Rizici su rast troškova, lokacija podataka i zaključavanje kod dobavljača.
9.6 Skaliranje, balanser i keš
NZ-1 kaže: 95 % zahtjeva dobija odgovor za najviše 2 sekunde, pri do 200 istovremenih korisnika. Koliko je to posla za server?
Procjena: kupac koji naručuje u prosjeku pošalje jedan zahtjev serveru na svakih 5 sekundi (otvori jelovnik, doda jelo, pogleda korpu…). Tada 200 korisnika šalje
\[ \lambda = \frac{200 \text{ korisnika}}{5 \text{ s}} = 40 \text{ zahtjeva u sekundi}. \]
Čemu služi. Ova procjena pretvara „200 korisnika” u broj s kojim inženjer može raditi. Ako jedan server DeliveryApp, izmjereno testom opterećenja, obradi 100 zahtjeva u sekundi uz odgovor ispod 2 s, jedan server je dovoljan i ostaje mu rezerva. Dva servera stavljamo zbog dostupnosti (9.3), ne zbog brzine. Da je procjena 400 zahtjeva u sekundi, trebalo bi bar četiri servera. Pravi broj se provjerava mjerenjem (poglavlje 14 i predmet Testiranje softvera), jer je pretpostavka „jedan zahtjev na 5 s” samo procjena.
Kad kapacitet ne dostaje, postoje dva načina skaliranja:
- Vertikalno – jači računar: više procesora i memorije. Jednostavno, ali ima granicu, i jedan jak računar je i dalje jedinstvena tačka otkaza.
- Horizontalno – više računara iste vrste. Teoretski bez granice, i daje redundanciju, ali traži da server ne pamti ništa o korisniku u svojoj memoriji (sve je u bazi), da bi svaki zahtjev mogao obraditi bilo koji server.
Kod horizontalnog skaliranja ispred servera stoji balanser opterećenja (load balancer): program koji prima sve zahtjeve i raspoređuje ih na servere, a server koji ne odgovara privremeno izbaci iz igre. Slika iz života: redar na ulazu u poštu koji ljude upućuje na slobodan šalter.
Još jedan alat za brzinu je keš (cache): brza memorija s kopijom podataka koji se često traže, a rijetko mijenjaju. Jelovnik Picerije R-1 traži svaki kupac, a mijenja se jednom sedmično. Umjesto da svaki put ide u bazu, server ga drži u kešu i odgovara za djelić milisekunde. Opasnost keša je zastarjela kopija: ako restoran označi Capricciosu kao nedostupnu, keš mora biti obrisan, inače kupci naručuju nešto čega nema. Kaže se, napola u šali, da su dvije najteže stvari u računarstvu davanje imena i brisanje keša u pravo vrijeme.

Ukratko.
- Za 200 korisnika s po jednim zahtjevom na 5 sekundi server prima oko 40 zahtjeva u sekundi.
- Vertikalno skaliranje je jači računar, a horizontalno više računara iza balansera opterećenja.
- Horizontalno skaliranje traži da server ne pamti korisnika u memoriji, nego u bazi.
- Keš ubrzava čitanje čestih podataka, ali se mora obrisati kad se podatak promijeni.
Provjeri se.
- Zašto je za DeliveryApp predložen modularni monolit? – Jer je tim mali; jedan program je jednostavniji, a jasni moduli se kasnije mogu izdvojiti.
- Kojem nivou oblaka pripada iznajmljen virtuelni server na koji sami instaliramo sve? – IaaS.
- Šta radi balanser opterećenja? – Raspoređuje zahtjeve na više servera i zaobilazi server koji ne odgovara.
Dio 3 – Kako se arhitektura crta i zapisuje
9.7 C4 model
Arhitektura se crta mnogo, i često loše: kutije bez imena, strelice bez značenja, sve na jednom crtežu. Programer i konsultant Simon Brown predložio je jednostavan pristup koji se zove C4 model, po četiri nivoa crteža koja počinju slovom C na engleskom. Svaki nivo je kao zumiranje na mapi:
| Nivo | Pitanje | Za koga | Mapa |
|---|---|---|---|
| 1. Kontekst (Context) | Ko koristi sistem i s kojim drugim sistemima razgovara? | svi, i ljudi iz posla | država |
| 2. Kontejneri (Containers) | Od kojih programa i baza se sistem sastoji i kako razgovaraju? | arhitekte, programeri, DevOps | grad |
| 3. Komponente (Components) | Od kojih modula se sastoji jedan kontejner? | programeri tog dijela | ulica |
| 4. Kod (Code) | Kako izgledaju klase jedne komponente? | programer | kuća (to je klasni dijagram iz poglavlja 6) |
Riječ kontejner ovdje ne znači Docker kontejner (poglavlje 14), nego bilo koji samostalan dio koji radi i čuva ili obrađuje podatke: mobilna aplikacija, web aplikacija, server, baza, red poruka.
Za većinu sistema dovoljna su prva dva nivoa. Pravila dobrog C4 crteža: svaka kutija ima ime, vrstu i jednu rečenicu šta radi; svaka strelica ima natpis šta se šalje i, kod kontejnera, kako (npr. „JSON preko HTTPS”); i uz crtež stoji legenda.
Mermaid ima podršku za C4 dijagrame. Kontekst DeliveryApp:
C4Context
title DeliveryApp – kontekst sistema
Person(kupac, "Kupac", "naručuje hranu s mobitela")
Person(restoran, "Osoblje restorana", "prima i priprema narudžbe")
Person(dostavljac, "Dostavljač", "preuzima i nosi narudžbe")
System(deliveryapp, "DeliveryApp", "aplikacija za naručivanje hrane iz tri restorana")
System_Ext(placanje, "Sistem plaćanja", "naplata karticom")
System_Ext(mape, "Servis mapa", "udaljenost i put")
Rel(kupac, deliveryapp, "naručuje, prati")
Rel(restoran, deliveryapp, "prihvata, javlja spremno")
Rel(dostavljac, deliveryapp, "preuzima, predaje")
Rel(deliveryapp, placanje, "naplati, vrati novac")
Rel(deliveryapp, mape, "udaljenost?")
Primijetite da je ovo isti kontekst kao u poglavlju 1 (slika 1.4) i poglavlju 4 (kontekstni DFD). Isti sistem, isti učesnici, drugi jezik crtanja.

Ukratko.
- C4 model ima četiri nivoa kao zumiranje mape: kontekst, kontejneri, komponente i kod.
- Kontejner je samostalan dio koji radi: aplikacija, server, baza, red poruka.
- Svaka kutija ima ime, vrstu i rečenicu, a svaka strelica natpis šta se šalje i kako.
- Za većinu sistema dovoljna su prva dva nivoa.
9.8 Kontejneri DeliveryApp
Kad zumiramo u DeliveryApp, vidimo šest kontejnera:
| Kontejner | Tehnologija (prijedlog) | Šta radi |
|---|---|---|
| Mobilna aplikacija | Android i iOS | jelovnik, korpa, plaćanje, praćenje; i aplikacija dostavljača |
| Web aplikacija restorana | preglednik na tabletu u kuhinji | nove narudžbe, prihvatanje, jelovnik, izvještaj |
| API server | Python, FastAPI (modularni monolit) | pravila PP-1 do PP-6, narudžbe, stanja |
| Baza podataka | PostgreSQL kao usluga, s replikom | narudžbe, jelovnik, kupci (šema iz poglavlja 8) |
| Red poruka | npr. RabbitMQ | događaji „nova narudžba”, „spremna”, „isporučena” |
| Servis obavještenja | Python | šalje push poruke i SMS kupcima i dostavljačima |
Novi dio u odnosu na ranija poglavlja je red poruka (message queue). Kad se desi važan događaj (restoran označi narudžbu spremnom), API server ne čeka da se pošalju sva obavještenja, nego događaj stavi u red i odmah odgovori restoranu. Servis obavještenja uzima događaje iz reda svojim tempom. Ako servis obavještenja na trenutak padne, poruke čekaju u redu i ne gube se. Slika iz života: poštansko sanduče. Poštar ne čeka da otvorite vrata; ostavi pismo, a vi ga uzmete kad dođete. O događajima i redovima više u poglavlju 10.
Mermaid ima i C4 dijagram kontejnera (C4Container, izvor je u primjeri/mermaid/s9_c4_kontejneri.mmd), ali kod mnogo veza sam bira nepregledan raspored, pa je slika 9.5 nacrtana posebno, s istim sadržajem.

Ukratko.
- DeliveryApp ima šest kontejnera: mobilnu aplikaciju, web aplikaciju restorana, API server, bazu, red poruka i servis obavještenja.
- Red poruka prima događaje od servera i predaje ih servisu obavještenja njegovim tempom.
- Ako servis obavještenja padne, poruke čekaju u redu, kao pisma u sandučetu.
9.9 Arhitektonske odluke (ADR)
Najveći problem arhitekture nije pogrešna odluka, nego zaboravljen razlog. Dvije godine kasnije novi programer pita: „Zašto ovo nije u mikroservisima?” Ako niko ne zna odgovor, tim ili ponavlja istu raspravu, ili mijenja odluku bez razumijevanja zašto je donesena.
Zato se svaka važna odluka zapisuje kao ADR (architecture decision record, zapis arhitektonske odluke). To je kratak Markdown fajl, jedna stranica, s ustaljenim dijelovima:
# ADR-001: Server kao modularni monolit
- Status: prihvaćeno
- Datum: 2026-10-15
## Kontekst
Tim ima četiri člana. Očekuje se do 200 istovremenih korisnika (NZ-1),
oko 40 zahtjeva u sekundi. Potrebna je dostupnost 99,5 % (NZ-2).
## Odluka
API server pravimo kao jedan program (modularni monolit) s modulima
jelovnik, narudzbe, placanje i dostava. Moduli razgovaraju samo preko
javnih funkcija. Pokrećemo dva primjerka iza balansera.
## Posljedice
+ Jednostavno puštanje u rad i testiranje za mali tim.
+ Dva primjerka daju redundanciju za NZ-2.
− Svi moduli se puštaju zajedno; greška u jednom može oboriti sve.
− Ako modul dostava zatreba nezavisno skaliranje, izdvojićemo ga (novi ADR).
## Razmotrene opcije
Mikroservisi (odbijeno: previše složenosti za četiri člana).Dobar ADR je kratak i iskren: navodi i loše posljedice, ne samo dobre. ADR se ne briše kad se odluka promijeni; piše se novi ADR sa statusom „zamjenjuje ADR-001”, tako da istorija odluka ostaje vidljiva, kao istorija stanja narudžbe u poglavlju 7.
Druga važna odluka za DeliveryApp mogla bi biti ADR-002: baza u produkciji. Na praktičnoj nastavi koristimo SQLite (jedan fajl, nula podešavanja), ali SQLite nije pravljen za mnogo istovremenih upisa sa više servera. Za rad sa stvarnim kupcima tim bira PostgreSQL kao uslugu s replikom (9.3, 9.5). Primijetite da šema iz poglavlja 8 ostaje skoro ista: to je prednost standardnog SQL-a.
Ukratko.
- Najveći problem arhitekture je zaboravljen razlog odluke.
- ADR je kratak zapis odluke: status, kontekst, odluka, posljedice (i loše) i razmotrene opcije.
- Promijenjena odluka dobija novi ADR koji zamjenjuje stari, pa istorija ostaje vidljiva.
- Za DeliveryApp su prve odluke ADR-001 (modularni monolit) i ADR-002 (PostgreSQL u produkciji).
Provjeri se.
- Koji nivo C4 modela pokazuje bazu i red poruka? – Nivo 2, kontejneri.
- Čemu služi red poruka u DeliveryApp? – Prima događaje od servera i predaje ih servisu obavještenja, tako da server ne čeka i poruke se ne gube.
- Šta ADR mora sadržati osim odluke? – Kontekst, posljedice (i dobre i loše), status i razmotrene opcije.
Praktična nastava – arhitektura DeliveryApp
Cilj je nacrtati arhitekturu DeliveryApp na prva dva nivoa C4 modela, izračunati dostupnost i opterećenje i zapisati dvije arhitektonske odluke. Fajlovi idu u arhitektura/ repozitorija deliveryapp-projekat.
Korak 1 – Kontekst (C4 nivo 1)
- U
arhitektura/README.mdprepišite C4 kontekst iz 9.7 (blokmermaid) i pogledajte ga u pregledu. - Dodajte aktera Administrator i vanjski sistem SMS pružalac s odgovarajućim vezama.
- Uporedite sa slikom 1.4 i kontekstnim DFD-om iz poglavlja 4: da li su učesnici isti? Ako nisu, uskladite.
Korak 2 – Kontejneri (C4 nivo 2)
- Prepišite
s9_c4_kontejneri.mmdizprimjeri/mermaid/uarhitektura/README.md. - Ako je Mermaid raspored nepregledan, nacrtajte isti dijagram u draw.io (kutije C4 su u biblioteci C4), s legendom.
- Za svaku strelicu između kontejnera zapišite u tabelu: ko šalje, kome, šta i kojim protokolom.
Korak 3 – Račun dostupnosti
U arhitektura/dostupnost.md, uz pretpostavku da svaki dio ima dostupnost 99,5 %, izračunajte (s postupkom):
- jedan server, jedna baza;
- dva servera, jedna baza;
- dva servera, baza s replikom;
- raspored 3 i u nizu red poruka i servis obavještenja (pitanje: da li kvar servisa obavještenja obara naručivanje? Ako ne, da li ga treba računati u nizu?).
Za svaki slučaj zapišite zastoj u satima ili minutama za mjesec od 30 dana. Rezultate prva tri slučaja uporedite s tabelom iz 9.3.
Korak 4 – Procjena opterećenja
Procijenite broj zahtjeva u sekundi za tri situacije: obično podne (200 korisnika, jedan zahtjev na 5 s), sportska utakmica u nedjelju (500 korisnika, jedan zahtjev na 4 s) i akcija „besplatna dostava cijeli dan” (pretpostavite sami). Ako jedan server obradi 100 zahtjeva u sekundi, koliko servera treba u svakoj situaciji, uz još jedan za redundanciju?
Korak 5 – Dva ADR-a
- Napišite
arhitektura/adr-001-modularni-monolit.mdpo šablonu iz 9.9, vlastitim riječima. - Napišite
arhitektura/adr-002-baza.md: kontekst (SQLite na vježbama, NZ-2 u produkciji), odluka, posljedice i bar dvije razmotrene opcije. - Opcionalno: ADR-003 o tome da li aplikacija saznaje promjenu stanja narudžbe tako što pita server svakih 10 sekundi ili joj server javlja (push). Navedite posljedice za bateriju mobitela i opterećenje servera.
Korak 6 – AI kao sagovornik arhitekte (opcionalno)
Dajte AI asistentu nefunkcionalne zahtjeve NZ-1 do NZ-5 i zatražite tri različite arhitekture za DeliveryApp, s prednostima i manama. Uporedite ih sa svojom i zapišite u ADR-001 pod „Razmotrene opcije” onu koja je najbolje obrazložena. Provjerite svaki broj koji AI navede (npr. dostupnost) vlastitim računom.
Rezultat koji se predaje: folder arhitektura/ s C4 dijagramima konteksta i kontejnera, tabelom veza, računom dostupnosti i opterećenja i najmanje dva ADR-a.
Vježbe
Vježba za studenta 1 – arhitektura ili ne.
Koje su od ovih odluka arhitektonske? a) boja dugmeta „Naruči”; b) da li se cijena računa na serveru ili u aplikaciji; c) naziv varijable ukupno; d) da li postoji red poruka; e) da li baza ima repliku; f) redoslijed polja u formi za adresu.
Rješenje. Arhitektonske su b), d) i e), jer se teško mijenjaju i utiču na cijeli sistem (sigurnost, pouzdanost, dostupnost). a), c) i f) se mijenjaju brzo i lokalno.
Vježba za studenta 2 – dostupnost.
Sistem ima tri dijela u nizu: balanser (99,9 %), server (99,5 %) i bazu (99,5 %). Kolika je dostupnost sistema i koliko sati zastoja dozvoljava u 30 dana? Ispunjava li NZ-2?
Rješenje. 0,999 × 0,995 × 0,995 ≈ 0,989035, dakle oko 98,9 %. Zastoj ≈ (1 − 0,989035) × 720 ≈ 7,9 sati. NZ-2 (najviše 3,6 h) nije ispunjen; potrebna je redundancija servera i baze.
Vježba za studenta 3 – redundancija.
Koliko je dostupan par paralelnih servera ako je svaki dostupan 99 %? A tri paralelna servera?
Rješenje. Dva: 1 − 0,01² = 1 − 0,0001 = 0,9999, dakle 99,99 %. Tri: 1 − 0,01³ = 1 − 0,000001 = 0,999999, dakle 99,9999 %. (Uz pretpostavku da kvarovi dolaze nezavisno.)
Vježba za studenta 4 – IaaS, PaaS ili SaaS.
Razvrstajte: a) DeliveryApp koristi gotov servis za slanje SMS poruka preko interneta; b) tim iznajmljuje virtuelni računar i sam instalira Python i PostgreSQL; c) tim šalje kod na platformu koja ga sama pokreće i skalira; d) restorani koriste gotov online kalendar za smjene konobara.
Rješenje. a) SaaS (gotova usluga); b) IaaS; c) PaaS; d) SaaS.
Vježba za studenta 5 – opterećenje.
U nedjelju za vrijeme utakmice DeliveryApp koristi 600 korisnika, a svaki šalje jedan zahtjev na svake 3 sekunde. Jedan server obradi 100 zahtjeva u sekundi. Koliko servera treba, uz jedan rezervni?
Rješenje. λ = 600 / 3 = 200 zahtjeva u sekundi. Za 200 zahtjeva treba 200 / 100 = 2 servera, plus jedan rezervni za slučaj kvara: 3 servera. (U praksi se ostavlja i rezerva kapaciteta, pa bi se rad servera mjerio testom opterećenja.)
Sažetak u pet rečenica
- Arhitektura su odluke o dijelovima sistema i njihovim vezama koje se teško mijenjaju, kao noseći zidovi kuće, a Netflix je 2008. naučio da jedna baza može biti jedinstvena tačka otkaza za cijeli posao.
- Troslojna klijent–server arhitektura drži prikaz na klijentu, a pravila i podatke na serveru, koji nikad ne vjeruje cijeni koju je poslao klijent.
- Nefunkcionalni zahtjevi pokreću arhitekturu: dijelovi u nizu množe dostupnost (0,995 × 0,995 ≈ 99,0 %), a redundancija je podiže (1 − 0,005² = 99,9975 %), pa tek dva servera i baza s replikom ispunjavaju NZ-2 sa sigurnom rezervom.
- Za mali tim DeliveryApp razuman izbor je modularni monolit u oblaku (PaaS i baza kao usluga), iza balansera, s kešom za jelovnik i redom poruka za obavještenja.
- Arhitektura se crta C4 modelom (kontekst, kontejneri, komponente, kod), a svaka važna odluka zapisuje se kao ADR s kontekstom i posljedicama, da razlog ne bude zaboravljen.