Herding av eksterne tjenester

Før studiestart i år integrerte vi oss mot en ny ekstern tjeneste for timeplaner levert av sektoren. Ved studiestart skapte denne tjenesten en del problemer for våre system. Tjenesten viste seg å være svært ustabil, noe som igjen resulterte i ytelsesproblem i våre interne system.

Siden en svært stor andel av trafikken rundt studiestart generer timeplanrelatert trafikk så resulterte manglende kontakt mot timeplantjenesten at våre interne tjenester ble overbelastet. Høyst sannsynlig skyldes dette ganske enkelt at den eksterne tjenesten ikke var dimensjonert for den økte trafikken vår bruk av tjenesten medførte.

Løsningen: Hystrix

For å få en rask løsning på problemet, og samtidig sørge for å herde oss mot eventuelle femtidige problem innførste vi Hystrix. Hystrix er et java-bibliotek laget av Netflix som har som mål å herde java-implementasjoner mot feil i eksterne tjenester og eksterne bibliotek. Altså å herde seg mot følgefeil som oppstår i eksterne tjenester man ikke selv har direkte kontroll over. Eller, som Netflix selv sier:

Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.

Hystrix er et svært kraftig bibliotek med svært mange muligheter. Den kontrollerer sine egne «thread pools» og har dermed har den mulighet for å isolere problem før de oppstår og omgå dem. Hystrix har en innebygd mellomlager-løsning, noe vi ikke har benyttet oss av da vi har vår egen mellomlager løsning. Hystrix har en kraftig monitoreringsløsning, og støtter både synkron og asynkron bruk.

Det er nærliggende å tenke at Hystrix bare er til for å herde web-tjenestekall, og det fungerer den utmerket til, men den kan herde en hvilken som helst kode som er utsatt for feil eller forsinkelser, om det er databasekall, lasting av filer, eller ganske enkelt tunge og kompliserte algoritmer.

Hver lille detalj for hver lille kodebit man ønsker å herde kan konfigureres. Et eksempel: Denne metoden skal det gjøres tiltak på dersom det oppstår mer enn 10 feil i løpet av 500ms, og et kall får ikke lov å ta lenger tid enn 100ms. Tiltaket er å bruke mellomlager, varsle brukeren om at mellomlager benyttes, og bruke et statisk svar dersom mellomlager ikke finnes. Når tiltak er gjennomført skal hvert 100 kall, eller etter 2 sekunder slippes gjennom for å sjekke om tjenesten er oppe igjen. Dette er selvfølgelig en grov forenkling og bare et eksempel. En bonus det er verdt å merke seg her er at standardverdiene Hystrix bruker dersom man velger å ikke konfigurere noe selv fungerer stort sett utmerket, så Hystrix føles nesten «plug and play» når man implementerer den.

Mulighetene og forklaringen på hvordan Hystrix fungerer er naturligvis mye større og mer komplekst en det som kan dekkes her, men en liten forklaring på grunnfunksjonaliteten, og den funksjonaliteten vi i hovedsak bruker skal vi klare. For hver bit med kode man ønsker å beskytte setter Hystrix opp en «threadpool» for, og pakker seg rundt den. Den holder til enhver tid oversikt over hvor mange ganger koden blir kjørt, hvor mange feil som har oppstått, og hvor lang tid den tar å kjøre. Dette gjør den i sanntid. Alle kall som feiler eller tar for lang tid vil bli rutet til en alternativ kode man selv definerer. Når antall feil eller treigheter når en definert terskelverdi, vil Hystrix åpne en «bryter». Når bryteren er åpen, vil ikke lenger koden som herdes bli kjørt. I stedet kjøres den alternative koden, man selv definerer, for alle nye kall (den alternative koden kan igjen beskyttes av Hystrix, men da begynner saker å bli komplekse). Så lenge bryteren er åpen vil også Hystrix slippe gjennom et og annet kall (avhengig kofigurasjonen) som sørger for å sjekke om koden som feilet har begynt å fungere igjen. Dersom det er tilfelle, lukkes bryteren igjen, og alt er tilbake til normalt. Alt dette gjøres i sanntid, og med svært lite «overhead».

circuit-breaker-1280

Opplevelse for sluttbrukeren

I tillegg til at implementasjonen vår herder systemet, slik at sluttbrukere ikke opplever ytelsesproblem når timeplanløsningen er utilgjengelig, har vi økt brukeropplevelsen betraktelig. Vi har nemlig implementertert den alternative metoden til å hente data fra et mellomlager vi vedlikeholder, dersom tilgjengelig. Tidligere løsning var slik at dersom tjenesten gikk ned, fikk studenter som forsøkte å se en timeplan en feilmelding om at tjenesten er utilgjengelig. Med det nye systemet vil man i all hovedsak likevell se en timeplan generert fra mellomlageret, med varsel om at den er generert fra mellomlager og kan derfor være noe utdatert eller være mangelfull. Dette betyr at når den eksisterende timeplanløsningen får trøbbel, vil de aller aller fleste studentene ikke merke noen endring overhode.

Montiorering

Som nevnt har Hystrix svært god og fleksibel mulighet for monitorering. Dette gjøres via egne sanntidsstrømmer, slik at man til enhver tid har mulighet for et sanntidsbilde av statusen på alle delene av systemet man har herdet. Det finnes en rekke «plug-ins» for ulike sanntidsstrømformater, noe som gjør at man enkelt kan sette opp Hystrix til å fungere sømløst med det monitorerings- og overvåkningssystemet man bruker. Her er et eksempel fra det enkle dashboardet vi har satt opp som en del av implementasjonen.

Selection_049

Vi kan i sanntid se hvor mange kall vi gjør mot den nye timeplantjenesten, hvor mange av kallene som feiler eller tar for lang tid, om «bryteren» er åpen eller lukket, og statistiske data på hvor lang tid hvert kall tar.

Fremover

Vi har nå herdet våre system som kommuniserer med den nye timeplanløsningen, FS-WS, samt SIO sin feed av student foreninger. I skrivende stund jobbes det med flere implementasjoner, og ønsket er at vi skal herde oss mot alle system både interne og eksterne som benyttes i sanntid. System hvor det kjøres bulk import gjennom batch-jobber er det ikke behov for å herde.

I tillegg er det ønskelig å utvide monitoreringen slik at man får mer enn bare en sanntidsoversikt og har tilgang til historiske data. Videre er det naturlig å se på automatisk varsling dersom en «bryter» har vært åpen over tid. Men dette ser vi på som en logisk del av et kommende prosjekt hvor vi ønsker å styrke vår monitorering til å omfatte flest mulig av våre interne system, samt de eksterne systemene vi integrerer mot hvor dette er naturlig.

Ellers er det også ønskelig at alle femtidige java-baserte system benytter seg av Hystrix for herding der hvor det er fornuftig. Det vil også være fornuftig å teste ut og vurdere tilsvarende løsninger for system skrevet i andre språk, der hvor det er mulig.