Hele Norge sjekka Vy-appen samtidig: – Det var vi ikke klare for!
I januar 2024 stanset all togtrafikk, og mediene oppfordret hele Norge til å åpne Vy-appen – samtidig. Nå forteller de hvorfor den gikk ned.
Den 17. januar 2024 snødde Østlandet ned og all togtrafikk stanset.
Da mediene samtidig gikk ut og oppfordret alle til å sjekke Vy-appen for mer informasjon, skulle det bli starten på den mest hektiske dagen noensinne for utviklerne i Vy.
– Det ble sendt ut en pressemelding til medie-Norge som oppfordret brukerne til å holde seg oppdatert via Vy-appen. Akkurat det var ikke vi utviklere klar for!
Det fortalte backendutvikler Heidi Elisabeth Sando i Twoday på JavaZone 2025 på Lillestrøm.
Sando jobber på prosjekt hos VyGruppen, og kunne sammen med techlead i VyGruppen, Simen Renberg, fortelle historien om dagen da alt som kunne gå galt, gikk galt.
– Alt Vy-appen kan gjøre, var nede, sa Sando.
Mange mikrotjenester som er avhengige av hverandre
Vy-appen består av en mange ulike tjenester:
- Reisesøk
- Pushvarsler
- Henting av tilbud
- Ordrehåndtering
- Betaling
- Billettering
Systemet er bygget på en mikrotjenestearkitektur, som betyr at hver tjeneste har ansvaret for sitt, snakker med andre mikrotjenester, og at de ulike mikrotjenestene skal skalere etter behov.
I Vys tilfelle var veldig mange tjenester avhengige av andre tjenester:
Denne arkitekturen hadde fungert helt problemfritt til nå.
Men selv om utviklerne hadde fulgt det som skal ha vært "best practice" for lastbalansereren, så taklet altså ikke systemet den massive trafikkøkningen.
Av ukjente årsaker begynte svartiden (latency) til tjenestene å øke kraftig, uansett hvor mye de prøvde å skalere opp.
Alt som kunne gå ned, gikk ned. Og utviklerne slet lenge med å skjønne hvorfor.
Databasen skalerte ikke
Etter hvert klarte utviklerne å nøste seg frem til årsaken:
Den kraftige økningen i trafikk gjorde at tilgjengelige databasetilkoblinger ble spist opp. Dette påvirket igjen andre tjenester.
Simen Renberg forklarte at de bruker Java-rammeverket Spring Boot, der hver HTTP-forespørsel får allokert en tråd til å utføre arbeidet sitt. Men når svartidene økte fra millisekunder til sekunder, klarte ikke systemet lenger å håndtere det økende antallet forespørsler, og "tråd-poolen" ble fylt opp.
Går du tom for tråder, svarer tjenesten med "error 503". Når nye forespørsler måtte vente lenge på databasetilgang, begynte ting å feile – og Vy fikk det Renberg kalte "cascading failures".
Alt ble en ond sirkel der tjenester brukte lenger og lenger tid på å svare, for så å feile helt.
Det hjalp ikke å skalere de ulike tjenestene ved å fyre opp noen flere containere.
– Da hadde vi plutselig 18 instanser som prøvde å få tak i databasen, i stedet for tre, sa Renberg.
– Rotårsaken var kort fortalt at vi slet veldig med å få skrevet raskt nok mot databasen vår.
Latency var ikke det eneste problemet
Renberg kunne fortelle at det ikke bare var databasen som lagde problemer. De hadde også en pushtjeneste som burde skalert. Det viste seg imidlertid at skalering basert på CPU-bruk var ineffektivt, også denne gangen fordi databasen var en flaskehals.
Vy bruker AWS SQS (Amazon Simple Queue Service) til å håndtere køen av pushmeldinger (som at et tog er forsinket eller innstilt). AWS SQS skriver til databasen, og så sendes det en pushmelding.
– Plutselig måtte én instans av pushmeldingstjenesten vår håndtere alle tog-trafikkhendelser i Norge dagen da alt gikk galt, sa Renberg.
Plutselig lå det 30.000 meldinger i køen.
Skal du skalere på CPU, må du være sikker på at det faktisk er CPU som er flaskehalsen når tjenesten din sliter, oppfordrer Renberg.
Måtte tenke nytt
Sando fortalte at det i praksis var to måter å løse problemet på – kaste penger på problemet, eller ikke kaste penger på problemet.
Hun understreker at det ikke nødvendigvis er noe galt å bare kaste mer penger på problemet når man opplever ekstrem pågang, for eksempel ved å skalere opp tjenester, databaser og annet.
– Det betyr bare at du har en populær app, sa Sando.
Men de var uansett nødt til å finne en mer varig løsning. Og en mer varig løsning var å programmatisk kontrollere ressursbruken under ekstreme belastninger, med blant annet:
- Circuit breakers. Vy bruker biblioteket Resilience4j for å hindre at eksterne tjenester blir overbelastet, ved å forhindre gjentatte mislykkede kall til tjenester.
- Load shedding. I stedet for å alltid prøve å håndtere alle forespørsler i ekstreme tilfeller, og dermed kollapse, er det bedre å sørge for å ta unna de viktigste. Her bruker Vy blant annet feature toggles som gjør at de ved problemer kan skru av de mest avanserte funksjonene i appen, eller redusere antall reiseforslag.
– Vi har blitt veldig glad i konseptet graceful degradation, hvor tanken er at det er bedre å gi en litt dårlig brukeropplevelse, enn ingen brukeropplevelse i det hele tatt, sa Renberg.
Har lært mye
Sando og Renberg fortalte at utviklerteamet har lært mye av hendelsen og gitt dem en dypere forståelse av flaskehalsene i systemet. Men det var vondt å ikke vite hva de skulle gjøre når det først gikk galt.
– Den aller største lærdommen var å kjenne på kroppen at vi ikke visste hva vi skulle gjøre, sa Sando.
Den viktigste oppfordringen de to hadde til publikum var å innrømme feil og lære av dem.
Aller, aller viktigst – kjør post mortems, innrøm feil og lær av dem.
– Aller, aller viktigst – kjør post mortems, innrøm feil og lær av dem, sa Renberg.
Det hører med til historien at Vy-appen og Vys nettsider faktisk gikk ned igjen på grunn av stor pågang dagen før de to skulle holde foredraget på JavaZone.
– Men det var gøy å se at en del av tiltakene vi hadde implementert hadde en effekt, selv om det ikke gikk helt smertefritt. Men ustabiliteten vi kjente på i en halvtime i går, får 17. januar til å føles som et ganske fjernt minne, sa Sando.