Objavljeno 28. maj 2026.

← Svi članci

Distribuirani sistemi

Outbox obrazac u mikroservisima

Jedan od najtežih problema u distribuiranim sistemima je da promene stanja u bazi i objavljivanje poruka ostanu usklađeni. Outbox obrazac to rešava tako što isporuku događaja čini pouzdanom čak i kod padova, ponovnih pokušaja i delimičnih ispada.

Skriveni problem u mikroservisima

Mikroservisi se često uvode radi bolje skalabilnosti, nezavisnog puštanja izmena i samostalnosti timova. U teoriji, svaki servis je vlasnik svojih podataka i komunicira preko API-ja ili asinhronih događaja.

Arhitektura deluje elegantno - dok sistemi ne počnu da padaju u stvarnim produkcijskim uslovima.

Distribuirani sistemi otkazuju drugačije od monolita. Umesto da jedna aplikacija potpuno padne, greške postaju delimične, nekonzistentne i teško ponovljive.

Servis za plaćanje može da uspe dok servis za obaveštenja tiho otkaže. Porudžbina može da se upiše u bazu, a da se rezervacija zaliha nikad ne desi. Poruka može da se objavi dvaput zbog ponovnih pokušaja. Druga poruka možda nikad neće biti objavljena.

Ovakve greške su posebno opasne jer sistem izgleda kao da radi, dok se poslovno stanje ispod polako kvari.

Distribuirani sistemi nisu teški samo zbog mreže. Teški su zato što se promene stanja dešavaju kroz više nepouzdanih komponenti.

Klasičan scenario otkaza

Uzmimo tipičan tok porudžbine u online prodavnici.

Servis za porudžbine primi zahtev i uradi dve stvari:

  • upiše porudžbinu u bazu
  • objavi događaj OrderCreated

Mnogi sistemi ovaj tok u početku implementiraju vrlo direktno:

saveOrder(order)

publishEvent(
  'OrderCreated',
  payload
)

Na prvi pogled logika deluje ispravno.

Ali zamisli da aplikacija padne posle uspešne transakcije u bazi, a pre nego što broker poruka primi događaj.

Porudžbina sada trajno postoji u bazi, ali servisi koji zavise od nje nikad ne saznaju za nju.

Zalihe nisu rezervisane.

Obrada plaćanja nikad ne počne.

Mejlovi se nikad ne pošalju.

Analitika postaje netačna.

Sistem ulazi u nekonzistentno stanje koje može ostati skriveno satima ili danima.

Ovakve greške se izuzetno teško otkrivaju, jer logovi često pokazuju uspešne upise u bazu, dok u brokeru poruka nema odgovarajućih događaja.

Zašto same transakcije ne rešavaju problem

Programeri ponekad pretpostavljaju da ih transakcije u bazi već štite od ovoga.

Nažalost, broker poruka i baza su dva različita sistema.

Transakcija u bazi ne može automatski da poništi objavu u Kafki ili neuspelu isporuku u RabbitMQ-u.

Postoje protokoli dvofaznog potvrđivanja (two-phase commit), ali oni donose dodatnu složenost, operativni teret, pad performansi i ograničenja skalabilnosti.

Većina modernih arhitektura za veliko opterećenje potpuno izbegava distribuirane transakcije.

Umesto toga, sistemi prihvataju eventualnu konzistentnost i fokusiraju se na pouzdanu komunikaciju.

Outbox obrazac

Outbox obrazac rešava problem tako što odlazne događaje čuva u istoj transakciji u bazi kao i samu poslovnu operaciju.

Umesto direktne objave brokeru, aplikacija upisuje događaj u outbox tabelu.

BEGIN TRANSACTION

INSERT INTO orders (...)

INSERT INTO outbox (
  event_type,
  payload,
  created_at,
  processed
)

COMMIT

Pošto se obe operacije dešavaju u istoj transakciji, ili uspevaju zajedno ili zajedno propadaju.

To garantuje da nijedan događaj ne može da nestane posle uspešnog upisa u bazu.

Poseban pozadinski proces stalno proverava outbox tabelu i objavljuje događaje na čekanju u RabbitMQ, Kafku, Amazon SQS ili drugu platformu za poruke.

while (true) {
  events = fetchPendingOutboxEvents()

  for (event of events) {
    publish(event)
    markAsProcessed(event)
  }
}

Ako broker privremeno nije dostupan, događaji ostaju bezbedno sačuvani u bazi dok isporuka kasnije ne uspe.

Tako nepouzdana distribuirana operacija postaje tok koji može da se oporavi.

Zašto Outbox obrazac tako dobro radi

Najveća snaga Outbox obrasca je što smanjuje broj sistema koji učestvuju u kritičnoj transakciji.

Aplikaciji je potrebno samo da transakcija u bazi odmah uspe.

Isporuka poruka postaje asinhrona i može da se ponavlja.

Ovaj pristup drastično povećava pouzdanost, jer su baze već izuzetno dobre u garantovanju trajnih upisa.

Outbox tabela praktično postaje trajni bafer događaja.

Donosi i nekoliko operativnih prednosti:

  • automatski ponovni pokušaji
  • mogućnost ponovnog puštanja događaja
  • revizija i praćenje sistema
  • podrška za dead-letter red
  • oporavak posle ispada
  • razdvojeni tokovi isporuke

Mnogi veliki sistemi koriste varijante ovog obrasca, jer je tokom pravih incidenata u produkciji pouzdanost važnija od elegancije arhitekture.

Idempotentnost je i dalje važna

Bitan detalj: brokeri poruka i sistemi za ponovne pokušaje mogu da isporuče događaj više puta.

Outbox obrazac garantuje da se događaji ne gube, ali ne garantuje obradu tačno jednom.

Zato potrošači poruka moraju bezbedno da podnesu duplikate.

Taj koncept se zove idempotentnost.

Servis za plaćanje, na primer, ne sme dvaput da naplati kupcu ako se isti OrderCreated događaj ponovo pusti pri ponovnom pokušaju.

Uobičajena rešenja su:

  • ključevi idempotentnosti
  • jedinstvena ograničenja u bazi
  • tabele obrađenih događaja
  • keš za uklanjanje duplikata

U distribuiranim sistemima, bezbedni ponovni pokušaji su često važniji od potpunog sprečavanja ponavljanja.

Skaliranje obrasca

Kako sistem raste, Outbox obrazac može dalje da se razvija.

Neke platforme dele obradu outbox-a po ID-ju agregata da bi sačuvale redosled poruka. Druge prenose promene iz baze preko CDC alata kao što je Debezium, umesto ručnog proveravanja tabele.

Veliki sistemi mogu i potpuno da odvoje transakciono opterećenje od infrastrukture za distribuciju događaja.

Uprkos ovim varijantama, osnovni princip ostaje isti:

Nikad ne dozvoli da promena poslovnog stanja uspe bez trajno sačuvanog događaja.

Zaključak

Mikroservisi donose fleksibilnost, ali i probleme distribuirane konzistentnosti koji ne postoje u klasičnim monolitima.

Outbox obrazac je postao jedan od najvažnijih obrazaca pouzdanosti u modernim distribuiranim arhitekturama, jer rešava jedan od najopasnijih načina otkaza: tiho izgubljene događaje.

Umesto krhkih tokova „sačuvaj pa objavi“, obrazac pretvara razmenu poruka u proces koji se može oporaviti i pratiti, izgrađen na garancijama trajnog skladištenja.

Za timove koji grade sisteme zasnovane na događajima, razumevanje Outbox obrasca je često razlika između teorijske arhitekture i pouzdanosti spremne za produkciju.

Pravimo pouzdane distribuirane sisteme

RankSoft pomaže timovima da povećaju pouzdanost sistema pod velikim opterećenjem kroz bezbednije strategije puštanja izmena, optimizaciju baze, asinhronu arhitekturu i inženjerske prakse fokusirane na produkciju.

Od modernizacije monolita do arhitekture zasnovane na događajima i optimizacije performansi, fokus je na merljivoj stabilnosti sistema, a ne na nepotrebnoj složenosti.

Porazgovarajmo o tvom sistemu →