Gæstebloggen

Derfor fejler dit website under load

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.

Martin Larsen er uddannet Master of Science (Cand. IT), Internet and Software Technologies og ansat som Director of Product hos SaaS-virksomheden hos Queue-it. Illustration: Privatfoto

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.

Relateret indhold

Kommentarer (8)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Gert G. Larsen

Det er sikkert rigtigt meget af det.
Hvis man sidder med små/mellem websites, og ikke har budget til at læse videre og købe den store hjælp til det, hvad er så top tre tips til at overkomme nogle af problemerne?

Jeg tænker sådan noget som f.eks.; tilmeld dit website til at køre gennem den gratis version af Cloudflare, det hjælper dig med xx, yy. Osv..?

  • 2
  • 0
Poul-Henning Kamp Blogger

Nu ved jeg godt at det er min egen tromme jeg slår på her, men et rigtig godt sted at starte er at sætte en maskine op med Varnish Cache som "efterbrænder" på webserveren.

Varnish tillader dig bestemme hvad der skal caches og hvor længe med 100% præcision og det gør ofte underværker for overbelastede servere at de slipper for alt "rutine-arbejdet" som f.eks billeder.

  • 11
  • 0
Jacob Christian Munch-Andersen

Moderne databaser har et cache-lag i rammen, sørg for at din database er sat op til at bruge det, og at kapaciteten er passende ifht. hvor meget ram maskinen har. Det er dog stadigvæk bedre at undgå databasekald.

Men det bedste man kan gøre for en dårligt skrevet side uden at skrive det hele om er nok at få sig et Varnish setup.

  • 0
  • 0
Gert G. Larsen

Tak PHK. Jeg har tænkt på Varnish flere gange, når jeg har sat sites op.
MEN hvad gør vi, i en situation hvor vi måske ikke har mulighed for at sætte en server op selv, og måske kun har adgang til eksempelvis et webhotel med noget præinstalleret software på, måske tilmed kun med FTP-adgang?
Kan man få Varnish som et CMS-plugin? Wordpress-plugin f.eks.?
Kan man købe en Varnish(-proxy? Hvad hedder det?) nemt ude i byen, ala Cloudflare? Er der en de-facto forhandler af disse, der "bare spiller"?
Kan man på nogle af de billigere danske webhotels forvente at de har en Varnish til rådighed, eller måske tilbyder det som ekstraservice?
Eller andre gode bud?

  • 1
  • 0
Palle Simonsen

Kan man på nogle af de billigere danske webhotels forvente at de har en Varnish til rådighed, eller måske tilbyder det som ekstraservice?

Bl.a. one.com anvender webcaching (varnish) - bare en servicemeddelelse, så hvis du er i markedet for WP m caching er det en mulighed.

Har selv haft brug for at disable caching et par gange under udvikling/test, men her er Google din ven:

.htaccess:
Header add "Cache-Control" "no-cache"

  • 1
  • 0
Klavs Klavsen

Lige præcis statiske billeder (som ikke kører forbi kode) kan det dog ikke betale sig at cache i varnish.. De fylder alt cache pladsen - og koster ingenting at levere fra backend serveren (og billeder burde flyttes til CDN url).
Og jeg vil klart anbefale at man får styr på cache headers i sin kode - og så har en varnish foran, der vil følge de regler som websitet sætter i dens svar headers.

Hvis man f.ex. opbevarer billeder i databasen (lad være med det) - eller på anden måde generer billederne i den størrelse klienterne beder om - så vil jeg anbefale at man sikrer sig at klienten beder om en url der ikke har GET parametre - men istedet er f.ex. /images/size/23/24/imagehest.jpg - og så få din kode til at skrive billedet til den præcise sti i dokumentroden af sitet (og hav styr på invalidering/sletning af de filer som relevant) - på den måde vil en rigtigt opsat apache/nginx - servere den direkte fra filsystemet så snart din kode har lavet det præcise billede én gang.
Og 1 varnish foran - vil sikre at der IKKE er nogen der får lov at bede om det samme billede samtidigt - så du undgår "thundering herd" problematikken ved første hit på nyt billede/ny size.

  • 2
  • 0
Log ind eller Opret konto for at kommentere
IT Company Rank
maximize minimize