IZVRŠNI SAŽETAK

PROBLEM

Platforma za javna upozorenja koja je držala više od 350.000 trajnih WebSocket konekcija i primala oko 65.000 poruka u sekundi postala je nestabilna tokom simulacija hitnih situacija sa visokom konkurentnošću. Obrada JSON-a zasnovana na stablu podigla je alokaciju na oko 14,2 GB/s, što je dovelo do G1GC pauza dužih od 1,8 sekundi (najgori slučaj oko 4,2 sekunde), znatno preko heartbeat prozora od 1 sekunde. Konekcije su istekle masovno, a naknadni talasi ponovnog povezivanja generisali su dodatnu alokaciju: alokacija -> GC pauze -> heartbeat timeout-i -> masovni diskonekti -> reconnect oluja -> nova alokacija

REŠENJE

SWARCS je uklonio alokaciju na izvoru: parsiranje JSON-a u stablo zamenjeno je streaming parsiranjem, a suvišno kopiranje podataka i kreiranje objekata na kritičnoj putanji prijema je smanjeno. G1GC je zatim podešen prema smanjenom profilu alokacije kako bi se održao prostor za rezervu tokom naglih skokova opterećenja. Nije dodat nikakav računski kapacitet.

KLJUČNI ARHITEKTONSKI POMAK

OD ekstremno kreiranje kratkotrajnih objekata + nepredvidive višesekundne pauze
→
KA značajno niži pritisak na alokacije + predvidiv GC sa niskom latencijom

ZAKLJUČAK

U ciljnom simulacionom opterećenju: Stopa alokacije memorije: 14,2 GB/s -> 3,8 GB/s, p99 trajanje GC pauze: 1.800+ ms -> < 85 ms, Prekidi WebSocket konekcija: 18,5% -> 0,0%, Reconnect oluje: Ponavljajuće -> Nije primećeno, Iskorišćenost CPU-a: Zasićena osnova -> ~35% niža. Ključna promena bila je uklanjanje nepotrebne alokacije sa kritične putanje izvršavanja, a zatim podešavanje kolektora prema dobijenom opterećenju.

ARHITEKTONSKA ANALIZA

KONTEKST I POSLOVNI UTICAJ

Platforma prosleđuje hitna upozorenja, obaveštenja o evakuaciji i telemetrijske podatke o opasnostima u realnom vremenu kroz geografske zone, do mobilnih uređaja, terenskih terminala i dispečerskih sistema službi za reagovanje u vanrednim situacijama.

  • kašnjenje hitnih obaveštenja
  • zastoj mrežne obrade tokom dugih JVM pauza
  • masovni prekidi WebSocket konekcija nakon isteka heartbeat rokova
  • talasi ponovnog povezivanja koji dodatno opterećuju infrastrukturu na ivici mreže
  • kaskadna degradacija tokom vršnih simulacija vanrednih situacija

Ključna karakteristika bio je mehanizam povratne sprege. Pauza duža od heartbeat granice mogla je istovremeno da utiče na veliki broj konekcija. Naknadni pokušaji ponovnog povezivanja zatim su stvarali dodatno opterećenje u sistemu koji je već bio pod pritiskom.

POVRATNA PETLJA OTKAZIVANJA

Prekomerna alokacija
         |
         v
    GC pritisak
         |
         v
  Duge STW pauze
         |
         v
Istek heartbeat roka
         |
         v
Masovni prekidi veza
         |
         v
  Reconnect oluja
         |
         v
Dodatna alokacija
         |
         +----------> GC pritisak

Inženjerski cilj bio je da se povrati predvidivo ponašanje runtime-a pri postojećoj operativnoj skali, umesto da se dodatnim ukupnim kapacitetom pokušava apsorbovati ista neefikasna putanja obrade.

UZROK I FORENZIČKA ANALIZA

Sloj za prijem koristio je Spring Boot, reaktivni WebFlux i Netty na Java 17 LTS, sa približno 32 GB JVM heap-a po čvoru, u klasteru od 8 čvorova. Tokom vršnih simulacija klaster je ispoljavao WebSocket timeout-e, prekide konekcija i zasićenje CPU-a. Povećanje infrastrukturnog kapaciteta nije uklonilo osnovni način otkazivanja: putanja prijema nastavila je da generiše prekomernu količinu prolaznog posla za svaku dolazeću poruku.

Dokazi su ukazivali na samopojačavajući mehanizam otkazivanja: prekomerna prolazna alokacija povećavala je GC pritisak; ozbiljne pauze prelazile su heartbeat granicu konekcija; masovni prekidi stvarali su dodatno opterećenje. Intervencija je zato morala da obuhvati i dominantni izvor alokacije i ponašanje kolektora pod nastalim opterećenjem. Otklanjanje samo simptoma ponovnog povezivanja ostavilo bi početni izvor pritiska netaknutim.

ARHITEKTONSKI UVID I EVOLUCIJA

Horizontalno skaliranje moglo je da poveća ukupan kapacitet, ali ne bi uklonilo nepotrebno kreiranje objekata za svaku dolazeću poruku. Redizajn je zato obuhvatio dva zasebna cilja: 1. Smanjenje nepotrebne alokacije na kritičnoj putanji prijema. 2. Podešavanje G1GC-a prema nastalom opterećenju i zahtevima za latenciju. Smanjenje alokacije rešavalo je izvor pritiska. Podešavanje GC-a uticalo je na ponašanje runtime-a nakon što je taj pritisak smanjen.

OD MATERIJALIZACIJE STABLA DO SELEKTIVNOG PARSIRANJA

STARI MODEL PRIJEMA

Mrežni payload
       |
       v
ObjectMapper stablo
deserijalizacija
       |
       v
Potpun graf objekata
+ privremeni objekti
       |
       v
Visoka stopa alokacije
    14,2 GB/s
       |
       v
GC pritisak i pauze
       |
       v
Otkazivanje heartbeat-a


REDIZAJNIRANI PRIJEM

Mrežni payload
       |
       v
Pooled Netty bafer
       |
       v
Jackson streaming parser
       |
       v
Selektivno izdvajanje polja
       |
       v
Niža stopa alokacije
    3,8 GB/s
       |
       v
G1GC podešen za opterećenje
       |
       v
Stabilne konekcije

KLJUČNE INŽENJERSKE ODLUKE

  • održavanje dodatnog rezervnog kapaciteta tokom naleta alokacije
  • obezbeđivanje dovoljnog kapaciteta za konkurentno sakupljanje u okviru ciljnog opterećenja
  • smanjenje rizika od neuspeha evakuacije i ozbiljne GC eskalacije
  • očuvanje responzivnosti aplikacije pod izmerenim opterećenjem

KVANTIFIKOVANI REZULTATI

Stopa alokacije memorije

PRE 14,2 GB/s
POSLE 3,8 GB/s

Smanjenje od 73%

p99 trajanje GC pauze

PRE 1.800+ ms
POSLE < 85 ms

Smanjenje od 95%+

End-to-end latencija isporuke (p99)

PRE ~2,1 s
POSLE ~310 ms

Unutar ugovornog cilja od 500 ms

Full GC događaji

PRE 9 po testu
POSLE 0 po testu

Nijedan Full GC događaj nije zabeležen nakon promene

Prekidi WebSocket konekcija

PRE 18,5% pod vršnim opterećenjem
POSLE 0,0%

Nisu zabeleženi prekidi konekcija

Reconnect oluje

PRE Ponavljale su se
POSLE 0 događaja

Nijedan događaj nije zabeležen

Iskorišćenost CPU-a

PRE Zasićeno početno stanje
POSLE ~35% niža

Povraćen procesni kapacitet

Sve brojke odnose se na ceo klaster i izmerene su tokom tri testa od po 45 minuta, sa ciljanim simulacionim opterećenjem za vanredne situacije.

Stopa alokacije pala je sa približno 14,2 GB/s na 3,8 GB/s, što predstavlja smanjenje od oko 73%. Pri brzini prijema od 65.000 poruka u sekundi, ove stope odgovaraju približno 218 KB i 58 KB ukupne alokacije po primljenoj poruci. To su izvedeni proseci na nivou celog klastera. Oni kvantifikuju opterećenje alokacijom povezano sa obradom poruka, a ne zaseban trošak alokacije samog parsera.

p99 trajanje GC pauze smanjeno je sa više od 1,8 sekundi na manje od 85 ms. Najduža pauza zabeležena nakon promene iznosila je 112 ms. Prekidi konekcija smanjeni su sa 18,5% na nula zabeleženih prekida, a tokom izmerenih testova nakon promene nisu zabeležene reconnect oluje.

Rezultati su dobijeni tokom simulacija vanrednih situacija na produkcionoj platformi, a ne tokom stvarne vanredne situacije. Oni opisuju testirano opterećenje i period posmatranja; ne garantuju iste rezultate pri drugačijim obrascima saobraćaja, hardveru, veličini heap-a ili runtime uslovima. Otkazi na nivou infrastrukture, kao što je gubitak mrežnog segmenta, nisu bili obuhvaćeni izmerenom intervencijom. Otpornost klijentskog ponovnog povezivanja, uključujući exponential backoff sa jitter-om, predstavlja komplementarnu meru koja nije bila deo izmerene promene.

Iskorišćenost CPU-a bila je približno 35% niža nakon intervencije. To je u skladu sa smanjenjem rada povezanog sa alokacijom i garbage collection-om, kao i sa manjim brojem prekida konekcija i pratećom obradom rukovanja konekcijama. Klaster je povratio procesni kapacitet bez povećanja računskih resursa.

Merenja pokazuju da je platforma stabilizovana u okviru ciljnog opterećenja bez dodavanja računskog kapaciteta. Pritisak alokacije, koji je najvećim delom poticao od obrade JSON-a u obliku stabla, dostizao je približno 14,2 GB/s, uz GC pauze duže od 1,8 sekundi. SWARCS je smanjio alokaciju na kritičnoj putanji prijema zamenom parsiranja JSON stabla streaming parsiranjem, a zatim podesio G1GC prema nastalom opterećenju. Kombinovana intervencija smanjila je pritisak alokacije i poboljšala uočeno ponašanje runtime-a. Tokom izmerenih testova, prethodni mehanizam otkazivanja izazvan dugim pauzama više nije dovodio do reconnect oluja.

INŽENJERSKI DOPRINOS

SWARCS je sproveo runtime forenziku, profilisanje alokacija, optimizaciju putanje prijema i podešavanje JVM-a prema opterećenju kako bi stabilizovao platformu.

ODGOVORNOSTI

  • profilisanje alokacija na putanji prijema visoke propusnosti pomoću JFR-a
  • identifikacija izgradnje JSON stabla kao jednog od dominantnih izvora alokacije
  • zamena obrade JSON-a u stablo streaming obradom pomoću JsonParser-a
  • smanjenje nepotrebnih alokacija i kopiranja mrežnih bafera
  • uklanjanje nepotrebnog boxing-a primitiva u reprezentacijama na kritičnoj putanji
  • kontrolisano ponovno korišćenje objekata tamo gde je profilisanje to opravdalo
  • evaluacija i konfiguracija G1GC-a za nastalo opterećenje
  • validacija ponašanja kolektora u odnosu na zahteve aplikacije u pogledu heartbeat-a
  • reprodukcija uslova visoke konkurentnosti sa više od 350.000 aktivnih WebSocket konekcija
  • validacija prijema pri brzini od približno 65.000 poruka u sekundi

KLJUČNA PORUKA

NE SKALIRAJ HORIZONTALNO DA BI PRIKRIO PRITISAK ALOKACIJE.

PROFILIŠI KRITIČNU PUTANJU.
UKLONI NEPOTREBNU ALOKACIJU.
PODESI KOLEKTOR PREMA IZMERENOM OPTEREĆENJU.
POŠTUJ MREŽNE I APLIKACIONE ROKOVE.
VALIDIRAJ PONAŠANJE RUNTIME-A POD REALISTIČNIM OPTEREĆENJEM.
MERI MEHANIZAM OTKAZIVANJA, A NE SAMO ISKORIŠĆENOST CPU-A.

U JVM sistemima sa visokim stepenom konkurentnosti dodatni hardver ne rešava nužno mehanizam koji sistem čini nestabilnim. Kada prolazna alokacija izaziva višesekundne pauze garbage collection-a, lokalni problem runtime-a može da pređe granicu sistema: propušteni heartbeat rokovi prekidaju konekcije, a talasi ponovnog povezivanja stvaraju dodatno opterećenje širom platforme. Inženjerski zadatak je da se identifikuje i ukloni izvor tog pritiska, a zatim da se ponašanje kolektora i aplikacije proveri u odnosu na stvarne zahteve za latenciju. U ovom slučaju, smanjenje nepotrebne alokacije promenilo je uslove izvršavanja koji su garbage collection pretvarali u pojačavač distribuiranog otkazivanja.