Hvorfor du ikke skal bruge AWS S3 eller CloudFront til at levere statiske aktiver

AWS er ​​DET seje barn i byen. Enhver sammenligning af forskellige skyudbydere er ufuldstændig, medmindre du sammenligner dem med AWS mindst en gang.

Men S3, den mest populære løsning til opbevaring i skyen og den, som alle elsker, bør ikke altid være dit valg. I denne artikel forklarer jeg hvorfor.

Bemærk: Du skal ikke straks råbe til mig om, hvordan og hvorfor AWS er ​​bedst. Jeg ved, at de er på toppen af ​​cloud computing - og på ingen måde prøver jeg at målrette mod nogen af ​​deres forretningspraksis og tjenester.

Jeg har lige brugt CloudFront + S3 selv sammen med DigitalOcean + Cloudflare også og har fastlagt mine observationer. Tag mine tanker konstruktivt, og hvis du tror, ​​jeg har lavet nogen fejl, så tweet mig på mehulmpt.

CloudFront + S3

CloudFront er en anden tjeneste, der ofte bruges (og anbefales) med S3, når du prøver at distribuere filer digitalt over hele kloden. CloudFront er en CDN fra Amazon med kantservere over hele verden. Sådan fungerer det:

Din bruger, for eksempel fra Indien, forsøger at indlæse dit websted, hvis server er placeret i USA. Lad os sige, at du bruger et SPA som React eller Angular. Den første index.html-side indlæses fra din oprindelsesserver (det er normalt en god praksis at aldrig cache HTML-sider, især hvis du bruger SSR-applikationer til at forhindre cache-uheld).

Derefter foretages disse opkald til et domænenavn fra CloudFront, som løses til en IP-adresse på en maskine tættest på din placering, hvis du har hostet dine JS / CSS-filer på CloudFront (S3). I dette tilfælde er det sandsynligvis en server fra AWS, der sidder i et datacenter i Mumbai, Indien.

Fra dette tidspunkt har serveren ansvaret for at levere den fil. To ting kan ske:

  • din fil er allerede tilgængelig med den Mumbai-server (cache), og den server returnerer den fil med det samme (cache-hit),
  • eller den har ikke den fil og skal udføre en tur til din oprindelsesserver (S3-bucket i dette tilfælde) for at hente den fil.

Men selvom der er en cache-miss, er chancerne store, at det stadig vil være hurtigere for en bruger sammenlignet med ikke at have CloudFront foran.

Hvorfor? Fordi når der er en cache-miss, og kantserveren prøver at nå frem til hovedserveren, bruger den en Tier 1 internetforbindelseslinje, der drives af Amazon - et billiont dollar amerikansk firma. De har sandsynligvis meget bedre internetforbindelse og latenstid end hvad din internetudbyder kan tilbyde.

Også fordi de er på det samme globale Amazon-netværk, kan de lave nogle pæne optimeringer for at spare mere tid.

I orden! Lyder godt for mig indtil videre, så hvad er problemet? Hold dine heste, vi kommer til det.

Aktivkomprimering

CloudFront giver dig mulighed for at levere komprimerede aktiver ved hjælp af GZIP. Men der er endda et køligere barn på markedet: brotli-kompression. Og det understøttes af næsten alle større browsere.

Brotli komprimerer dine transmissionsdata endnu mere. Dette betyder, at det ikke kun er godt på din tegnebog, men det er også godt for slutbrugeren (fordi de bruger mindre tid på at se den læssende / hvide skærm).

Amazon CloudFront understøtter endnu ikke levering af komprimering af brotli. Og jeg vil heller ikke bebrejde dem for dette. Dette skyldes, at komprimering af brotli er langsomt at gøre på farten (CloudFront gzip på farten), så de har ikke implementeret det endnu.

Sikker på, så lad os gøre det selv og gemme det på S3 og levere den komprimerede version, ikke? Desværre er det ikke så simpelt, og vi vil snart dreje ned til mere af et arkitekturproblem.

En typisk aktiv-URL vil se sådan ud: //mysite/assets/javascript/file.js

Når din browser fremsætter en anmodning, sender den en overskrift: Accept-Encoding. Denne header kan indeholde komprimeringsalgoritmer, som din browser kan understøtte, som gzip, deflate, brotli osv. Serveren skal nu handle smart for at få maksimal effektivitet.

  1. Hvis klienten understøtter brotli, skal du altid levere det brotli komprimerede aktiv.
  2. Hvis klienten understøtter gzip, skal du altid levere gzip.
  3. Ellers skal du levere den originale fil.
  4. Sørg også for, at den korrekte indholdskodning er angivet i responstypen, så browseren kan genkende komprimeringsalgoritmen.

Nu skal du først oprette 3 varianter af hver enkelt aktivfil:

  1. file.js
  2. file.js.br - brotli
  3. file.js.gz - gzip

Og du er nødt til at levere dem betinget afhængigt af, om browseren understøtter det eller ej. CloudFront er et "dumt" CDN - det vil bare kortlægge din anmodnings URL til filen på din server. Det kan ikke udføre nogen transformationer, medmindre .... du tilmelder dig en anden AWS-tjeneste - Lambda @ edge-funktioner

Vi ved sandsynligvis alle, hvad Lambda er på AWS - du kan køre funktioner i skyen uden at bekymre dig om underliggende infrastrukturopskalering eller nedskalering. Prissætning pr. API-anmodning, tidsbegrænset, sød. Lambda @ edge er en lignende tjeneste, men blev lavet til kantservere (CloudFront CDN datacentre)

Du kan teknisk konfigurere en Lambda-server til at fungere som en "mellemmand" mellem anmodningen fra din klient og CloudFront CDN. Lambda kan åbne anmodningen, se de understøttede indholdsoverskrifter, ændre URL'en i overensstemmelse hermed og videresende den til den "dumme" CloudFront, som derefter vil hente den ændrede URL-fil.

For eksempel, hvis Lambda ser, at browseren sendte en Accept-Encoding: br, kan lambda bruges til at ændre anmodnings-URL'en fra /javascript/file.js til /javascript/file.js.br uden faktisk at fortælle brugerens side. Cloudfront vil nu hente en mindre nyttelast og returnere et svar til en brotli-kodning. VINDE!

Men det er godt, ikke? Hvor er problemet? Problemet er ... prisfastsættelse.

AWS er ​​latterligt dyrt (til denne opgave)

Uanset hvad du har gjort indtil videre lyder det og ser meget godt ud. Men når du ser på, hvad der sker, når du begynder at ramme betydelige tal, vil du indse, at AWS ikke er fantastisk, når det kommer til dataoverførsel. Zoom sprang bare AWS af samme grund.

Plus, med aktivkomprimering, skal du nu også betale for Lambda @ edge-opkald. Jeg regnede med, at implementering af Lambda @ edge faktisk reducerer dine omkostninger, ellers betaler du meget mere for AWS for trafik!

CloudFront arbejder på dataoverførselspriser. Det opkræver ikke dig, når det henter data fra S3-skovlen, det oplader dig, når en bruger henter data fra kantserverne.

Øvre omkostningsbundet

I det dyreste land - Indien - opkræver CloudFront dig $ 0,170 pr. GB overført data. Dette er enormt!

Lad os sige, at du har et populært (hovedsageligt) indisk websted med omkring 50.000 brugere, der besøger dit websted dagligt. Lad os også sige, at du foretager nogle designændringer hver uge på dit websted (ret almindeligt for produkter med hurtig iterering), så du bliver nødt til at ugyldiggøre browseren og CloudFront-cachen.

Lad os også antage, at en enkelt bruger i gennemsnit downloader ca. 10 MB af det statiske aktiv fra dit websted (inkluderer CSS / JS / billeder / skrifttyper), der hostes på S3, der er proxyet gennem CloudFront.

Lad os beregne omkostningerne:

  1. 50.000 indiske brugere
  2. 0,17 USD pr. GB
  3. 10 MB pr. Bruger
  4. Hver bruger henter dette 4 gange om måneden (du skyller din cache 4 gange - en gang hver uge)

Omkostninger = 50000 * 0,17 * (10/1024) * 4 = 332 USD. Det er din OMKOSTNING ved netop dataoverførsel! Jeg beregnede ikke S3-lageromkostningerne og hostingwebsiteomkostningerne. (Jeg inkluderede heller ikke lambda-prisfastsættelse, fordi det ikke er meget => $ (0,20 * (50.000 * 4)) / 1 million = 4 cent.)

Lavere omkostninger bundet

Lad os i dette tilfælde antage et USA-baseret trafikwebsted. Parametrene nu ville være:

  1. 50K USA-brugere
  2. 0,085 USD pr. GB
  3. 3 MB pr. Bruger
  4. Hver bruger henter dette 4 gange om måneden (du skyller din cache 4 gange - en gang hver uge)

Omkostningerne = 50000 * 0,085 * 3 * 4/1024 = 50 USD. Det er det laveste, du betaler, når du bruger CloudFront med den nævnte trafik (i betragtning af at alle dine 50K-brugere kun er fra USA). Og husk, det er kun prisen for dataoverførslerne! (Ikke inklusive serveromkostninger til hosting af dit websted.)

Alternativ

Lad os sige, at du nu er vært for alle disse statiske aktiver på din hovedserver - reverse proxied af NGiNX og siger, kører på en $ 60 DigitalOcean-forekomst.

Din dataoverførsel pr. Måned = 50000 * (10/1024) * 4 = 1952 GB ca. 2 TB - DigitalOcean dækker din 1 TB overførsel pr. Dråbe gratis. Og det er $ 10 pr. 1 TB fra da, så det vil være $ 70 netto for at køre serveren.

Sikker på, du får noget ventetid nu - fordi du er vært for det selv (vi retter endda dette senere). NGiNX er en højtydende webserver, og du kan stole på, at den ikke er en flaskehals i din statiske aktivlevering.

Så du droppede bare omkostningerne ved "kun aktivoverførsel" fra $ 332 til $ 70 for at køre hele serveren! Bonus tip? Vi fokuserede kun på at køre dette i Indien, så brug en DigitalOcean-server fra Indien. Dette ville betyde mindre ventetid.

Ikke kun dette, men du kan også vælge Cloudflare CDN - hvilket er GRATIS. Cloudflare respekterer ikke dine filer for at opbevare i CDN, hvis de er for store eller for sjældent tilgængelige. Men vi antager et helvede af et populært sted her, så vi skal have det godt. Hvis ikke, vælg enhver anden CDN-tjeneste, og jeg garanterer dig, at den vil være mindre end $ 332 om måneden.

TL; DR - Hvis du er vært for et websted med mellemstore trafikmængder med regelmæssigt planlagte opdateringer, er det meget mere omkostningseffektivt at være vært for aktiver selv og bruge eksterne CDN'er (eller endda ting som DigitalOcean CDN) i stedet for at bruge S3 og CloudFront (hvor datatrafikhastigheder er gennem taget).

Konklusion

Jeg brugte denne opsætning (CloudFront + AWS S3) på codedamn.com - en platform for udviklere at lære og vokse. Jeg indså hurtigt, at selv om det ser fancy ud, og jeg har lagt kodetamn i de store ligaer - Amazon - er det bare ikke effektivt nok.

Er du enig med mig? Hvad synes du? Lad mig vide ved at kvidre på mig på min Twitter eller nå ud til mig på Instagram.

Fred!