Du har brugt dit budget på SoMe, reklamer og forberedelse til det, der skulle være årets kampagne, blot for at se dit website bukke under for de tusindvis af besøgende som forgæves prøver at tilgå websitet, men som nu mødes af lange svartider og http-fejlkoder.
Katastrofen er sket, men hvad gik galt? 8 års erfaring med udvikling og drift af Microservices i Queue-it – en SaaS applikation som dagligt har hundredetusindevis af samtidige brugere – har vist mig, at det normalt ikke er én ting, så her er et par bud.
Din monitorering er mangelfuld
Selvom monitorering ikke gør din applikation skalerbar, er det alligevel grundstenen i dit forsvar.
Du er allerede bagud hvis du ikke har indsigt i din applikations metrikker, du ikke bliver alarmeret ved fejl eller din log ikke er let tilgængelig. Dine reaktionsmuligheder er reduceret betragteligt.
Post-mortem er data også altafgørende for at kunne lave en effektiv optimering af systemet, som ikke er baseret på antagelser om årsagen.
Hvis din applikation er en black box er der gode nyheder, da der findes en væld af Log Management og Application Performance Management (APM) SaaS-produkter, som kan hjælpe dig, og det er let at komme i gang.
Din cache strategi er ikke fra dette årti
Et typisk forretningskrav er, at de data der vises på websitet – fx lagerstatus - er opdateret i realtid, og mange gange bliver disse krav uden tøven omsat til queries på databasen. Det virker muligvis som en fornuftig ide fra et forretningssynspunkt, men det er en virkelig dårlig ide hvis du prøver at lave et skalerbart system, som du samtidigt kan betale.
Caching er en af de mest effektive og billige måder at forbedre skalerbarhed og performance, og det kan implementeres på infrastrukturen, i applikationen eller på datalaget. Hvert lag har sine fordele, men infrastrukturen er klart der hvor de største og letteste tiltag kan laves.
Hvis du ikke har et Content Delivery Network (CDN) foran dit website er det en oplagt mulighed, og hvis du allerede har, er der en god sandsynlighed for at du ikke udnytter det optimalt.
Traditionelt har et CDN leveret statisk indhold som fx billeder, men i dag gør det meget mere, som fx caching af dynamisk indhold, routing, DDoS protection og mange tilbyder tilmed at afvikle din kode. Alt sammen gør at du i højere og højere grad kan flytte dit website ud på CDN-udbyderens infrastruktur.
Dit system bruger én databaseteknologi
I årtier har vi udviklet applikationer primært baseret på SQL-databaser. Høje priser på lagring af data og softwarelicenser har skabt en kultur hvor vi misbruger den relationelle datastruktur til fx at gemme billeder eller transient data som fx session state. SQL-databasen er et godt værktøj, men kun et af mange, og i et skalerbart system skal der bruges mange – ikke et.
Samtidigt er vi blevet opdraget til at data skal normaliseres ned i atomer, uden hensyn til at det skal sættes sammen, før det igen kan bruges til noget nyttigt. Resultatet er komplekse SQL-forespørgsler som langsomt dræber database performance.
Løsningerne kan være mange, inklusive document, time series, memory eller graph databaser, message streams eller måske et pattern som Command Query Responsibility Segregation (CQRS) der genererer optimerede read modeller.
Hver use case har sine egne egenskaber og krav, og skal det skalere kræver det forskellige værktøjer.
Dine forretningsprocesser skal laves om
Vi har traditionelt modelleret vores applikationer omkring de fysiske processer og transaktioner der eksisterer i den fysiske verden. En webshop vil fx typisk gennemføre en synkron authorize transaktion på kredit kortet som en del af købsprocessen på samme måde, som det foregår kiosken nede på hjørnet.
Problemet er at vi nu har høj kobling mellem webshoppen og betalingsservicen, og webshoppens performance nu er begrænset af skalerbarheden og oppetiden af betalingsservicen. I et skalerbart system er services autonome og benytter asynkrone workflows i en eventually consistent arkitektur.
Hvis du har handlet hos Amazon har du måske prøvet at få en e-mail om at din betaling ikke er gået igennem og du skal indtaste kortinformationer igen. Det skyldes at betalingen først gennemføres efter at ordren er gennemført og brugeren har fået sin ordrebekræftigelse.
Systemet kan altså efterfølgende gennemføre transaktionerne i den hastighed betalingsservicen kan håndtere, mens webshoppen kan tage imod et antal ordrer, som i perioder er væsentligt større end kapaciteten på betalingsservicen.
Størstedelen af de transaktioner vi implementerer i vores applikationer er ikke nødvendige, men hvis de skal konverteres til asynkrone skalerbare workflows kræver i mange tilfælde at forretningsprocesserne også ændres.
Din applikation kan ikke forøge kapaciteten
Uanset arkitekturen i din applikation vil der altid være begrænsninger. En skalerbar applikation vil dog kunne udnytte sin elasticitet til at udvide kapaciteten. Optimalt skalerer et system horisontal ved at tilføje flere servere til et cluster, og kapaciteten fordobles, når antallet af servere fordobles. Fordelen er at systemet – automatisk eller manuelt – let kan regulere kapaciteten til den aktuelle efterspørgsel.
Traditionelt skalerer mange applikationer dog vertikalt ved at serveren udskiftes med en større eller mindre server, hvilket ofte kræver mange ressourcer samt nedetid i større eller mindre grad. Skalering bliver mere og mere kostbart i en vertikal model, på grund af udgifter til administration, hardware og licenser. At udvikle et horisontalt skalerbart system er dog hverken let eller gratis.
En alternativ eller supplerende tilgang er at nedgradere brugeroplevelsen i takt med at systemet løber tør for ressourcer. En avanceret database CPU-heavy søgefunktion kan fx udskiftes med en simpel for at frigøre databasens CPU til andre formål.
Endelig kan man vælge kun at give en delmængde af brugerne adgang med det samme, og omdirigere de overskydende til en ekstern vente- eller køside, som ikke belaster systemet.
Du er ikke forberedt
Selv med den bedste arkitektur, de bedste udviklere og en fantastisk infrastruktur vil din applikation stadig have begrænsninger. Du har nok en form for distribueret system, og netværk, latency, trådhåndtering m.v. introducerer en række nye fejlkilder som vil begrænse skalerbarheden af applikationen.
Her er det essentielt, at du kender disse begrænsninger og får dem forbedret inden fejlen sker i produktion ved systematisk at loadteste din applikation. I starten vil du formentligt opleve at hver loadtest vil eksponere en ny begrænsning. Derfor er det vigtigt at afsætte god tid og køre flere iterationer hvor performancebegrænsninger identificeres og rettes.
Husk også at ny kode potentielt introducerer nye begrænsninger, så det er vigtigt periodisk at eksekvere dine loadtests.
Hvis du er interesseret i hvordan du let og billigt kommer i gang med at loadteste, kan du læse min blogserie Less Painful, Almost Free, Web Load Testing.

...men det er dyrt at lave god journalistik. Derfor beder vi dig overveje at tegne abonnement på Version2.
Digitaliseringen buldrer derudaf, og it-folkene tegner fremtidens Danmark. Derfor er det vigtigere end nogensinde med et kvalificeret bud på, hvordan it bedst kan være med til at udvikle det danske samfund og erhvervsliv.
Og der har aldrig været mere akut brug for en kritisk vagthund, der råber op, når der tages forkerte it-beslutninger.
Den rolle har Version2 indtaget siden 2006 - og det bliver vi ved med.