Den beste måten å være vert for en enkeltsidesapplikasjon (SPA) i Microsoft Azure

Tradisjonell Azure App Service vs. Azure Functions V2 med Proxies vs. Azure Storage Statisk Nettsted (forhåndsvisning)

Jeg trenger ofte å distribuere statiske nettsteder (f.eks. Vår bedriftsnettsted https://www.media-lesson.com) eller Single Page-applikasjoner, og jeg leter alltid etter måter å forbedre kostnadene og tid til å distribuere.

Microsoft kunngjorde nylig offentlig forhåndsvisning av statisk webhotell for Azure Storage og legger til enda et alternativ for å være vert for en enkeltsidesapplikasjon (SPA) på Azure.

Rett før Microsoft la tilbake støtte for Proxies i Azure Functions Runtime 2.0.11776-alpha den 14. mai, noe som ga en måte å være vert for et statisk nettsted i Azure Storage og videresende trafikk gjennom en Azure Function-proxy-rute.

Begge de nye alternativene legger til den tradisjonelle måten å være vert for (statisk) nettsted i en Azure App Service. Det er enda flere alternativer for å være vert for nettsteder i Azure, f.eks. bruker Containers, Docker, Kubernetes, Virtual Machines etc., men jeg vil holde fokus på enkle og kostnadseffektive distribusjoner av applikasjoner på en side.

Og siden vi vurderer vertsalternativer, er det også verdt å sammenligne manuell og automatisk distribusjon ved hjelp av Visual Studio Team Services (VSTS) for de nevnte tjenestene.

La oss svare på disse spørsmålene for å avgjøre hvilken tjeneste du skal bruke når du er vert for en enkelt sidesøknad:

  1. Hvor mye krefter er det å manuelt og automatisk distribuere en app?
  2. Hvor mye konfigurasjon er nødvendig?
  3. Hvordan skalerer det?
  4. Hvordan presterer den?
  5. Hvor mye koster det?

Testapp

La oss starte dette eksperimentet med å lage en enkel SPA basert på Angular ved å bruke Angular CLI som en test-app for å distribuere og teste på de tre forskjellige tjenestene: ng ny testapp - prosjektering Vær oppmerksom på at jeg direkte legger rutingsfunksjonen til appen ved hjelp av parameteren --routing. Jeg synes dette er et viktig aspekt å teste når jeg ser på vertsalternativer da ruting kan være en konfigurasjonsutfordring i noen miljøer som App Service fordi vi må konfigurere webserveren slik at rutetilgang kan håndteres av klientappen vår i stedet for serversiden.

For å teste ruting fullstendig, trenger vi også å ha noen prøveveier. La oss derfor legge til et hjem og en om-komponent til appen vår ved å bruke CLI: ng generere komponent hjemme og ng generere komponent om. Deretter må vi ha to ruter i app-routing.module.ts for å tillate navigering mellom de to komponentene:

Endelig noen navigasjonsknapper som lar brukeren navigere mellom de to komponentene i app.component.html:

La oss bygge appen vår lokalt for å forberede manuell distribusjon ved hjelp av ng build - som gir oss denne lille mappen med bygge-gjenstander:

Selvfølgelig ønsker vi også å tørke automatisk distribusjon som en del av en kontinuerlig distribusjonsprosess. La oss derfor skyve appen vår til et VSTS-lager og sette opp en build-definisjon med disse tre oppgavene:

npm installasjon

npm bygg

Publiser bygge artefakt fra bane dist til app

Azure App Service

Azure App Service er et PaaS-tilbud (Platform as a Service) og den klassiske måten å være vert for webinnhold på Azure. Ved å bruke apptjeneste må vi ta vare på konfigurasjon og skalering av tjenesten vår for hånd. For å teste dette, la oss lage en ny apptjeneste i Azure Portal. Jeg velger S1-nivå for denne testen, fordi det er nivået på inngangsnivå for produksjonsapper.

Konfigurer ruting

På grunn av dets natur å være et PaaS-tilbud, skal utviklere ta seg av konfigurasjonen av den underliggende webserveren (i tilfelle Windows er IIS). Dette betyr for å muliggjøre ruting i vår Angular-app, må vi gi en web.config-fil med instruksjoner for webserveren hvordan du håndterer ruting eller vert for den kantete appen i en ASP.Net Core 2.1-app med SpaServices mellomvare aktivert. Her en enkel prøve av en web.config med SPA-ruting:

Manuell distribusjon

For manuell distribusjon, la oss bare bruke FTP for å laste opp innholdet i dist-mappen vår og web.config til mappen wwwroot i apptjenesten. FTP-opplysningene kan lastes ned i Azure-portalen i oversiktsfanen for apptjenesten ved å klikke på "Få publiseringsprofil".

Kontinuerlig distribusjon ved hjelp av Visual Studio Team Services

Å sette opp en utgivelsesdefinisjon i VSTS for å distribuere appen til apptjenesten er ganske rett frem, da vi bare trenger en tom utgivelsesdefinisjon med en oppgave:

For å konfigurere et FTP-tjenesteendepunkt, la oss klikke på "Administrer" og legge til et nytt generisk endepunkt med de samme legitimasjonene som brukes for manuell distribusjon.

Azurefunksjoner

I denne varianten kommer vi til å bruke Azure Storage som en billig butikk for våre statiske filer og en Azure Function-app med fullmakter for å betjene SPA til brukeren. Dette lar oss skalere automatisk (når vi bruker forbruksplanen), kombinere SPA-en med andre funksjoner (f.eks. API-anrop) under ett domene og administrere appen vår på en serverløs måte.

Så vi må lage en funksjonsapp og en lagringskonto (opprettet automatisk når du oppretter en funksjonsapp). Deretter må vi lage en klatebeholder med navnet "web" i lagringskontoen, hvor vi vil distribuere filene våre til senere.

Rutemagien skjer nå på den måten vi konfigurerer fullmakter til å videresende forespørsel fra vår funksjonsapp til lagringskontoen. Derfor trenger vi to fullmektiger:

Den første som videresender forespørsler til basis-url til index.html

og en andre for å videresende forespørsler om andre statiske eiendeler som JavaScript-filer eller stilark til deres plassering i lagringskontoen.

Manuell distribusjon

For å distribuere manuelt klikker du på "Containere" i lagringskontoen i Azure-portalen og velger "web" -containeren som vi nettopp opprettet. La oss nå laste opp filene fra den lokale bygningen.

Kontinuerlig distribusjon ved hjelp av Visual Studio Team Services

For å teste dette må vi lage en andre utgivelsesdefinisjon i VSTS med den tomme prosessmalen og legge til AzureBlob File Copy oppgaven:

Azure Storage

Dette er det nyeste alternativet som nylig gikk inn i offentlig forhåndsvisning. Tanken er å bruke lagring for å være vert for SPA fordi en ekte webserver ikke er nødvendig for å tjene bare statiske filer som kvalifiserer denne varianten for buzzword “serverless”. Så la oss opprette en ny lagringskonto (general purpose v2) og aktivere den statiske nettstedfunksjonen:

Dette er all konfigurasjon vi trenger. Lagring skaleres automatisk og ruting fungerer også ut av esken. Det primære endepunktet er vår SPA-adresse. Hyggelig!

Manuell distribusjon

For å manuelt distribuere klikker du på "Containere" i lagringskontoen i Azure-portalen og velger "$ web" -beholderen (som opprettes automatisk når du aktiverer statisk nettsted). La oss nå laste opp filene fra den lokale bygningen:

Og det er det!

Kontinuerlig distribusjon ved hjelp av Visual Studio Team Services

For å teste dette må vi lage en tredje utgivelsesdefinisjon i VSTS med den tomme prosessmalen og legge til AzureBlob File Copy oppgaven:

Sørg for å velge versjon 2. * (forhåndsvisning), ellers mislykkes distribusjonsvaken fordi "$" -tegnet i beholdernavnet ikke var tillatt tidligere.

Opptreden

For å få en ide om ytelsen, la oss kjøre noen artillery.io belastningstester på våre 3 distribusjoner. Her er resultatene mine når jeg avfyrer 1 000, 10 000 og 100 000 forespørsler:

Det er en drastisk ytelsesfordel ved å bruke Azure Storage og unngå webserverkomponenten mens Funksjoner og App Service kjøres med en sammenlignbar hastighet. Dette er fornuftig ettersom begge deler den samme underliggende infrastrukturen. Jeg er litt overrasket over at Funksjon-appen kjører enda tregere enn App-tjenesten.

Jeg synes dette er fremmed når jeg sammenligner den totale driftstiden for å fullføre testen på 100 000 forespørsler. Dette tok rundt 46 sekunder å fullføre til Azure Storage og 14 minutter og 27 sekunder for App Service og til og med 17 minutter og 2 sekunder for Funksjon-appen. Jeg hadde forventet at Funksjon-appen skulle få fart over tid, da jeg ventet at den skalerer horisontalt automatisk. Som ikke ser ut til å fungere i dette scenariet.

Så vi har en klar vinner i denne disiplinen: Lagring er veldig raskt!

kostnader

Å få kostnadene riktig er vanskelig fordi alle har forskjellige faktureringsmodeller. Her er min eksempelberegning for månedlige kostnader for 100.000 forespørsler / dag i Vest-Europa-regionen (som jeg ikke er 100% sikker på at den er fullstendig og nøyaktig!):

Apptjeneste

1x S1-forekomst i Vest-Europa som kjører Windows (1 kjerne, 1,75 GB RAM, 50 GB lagring) = 61,56 € / måned

Funksjons-app (+ lagring)

Vårt SPA består av 5 filer * 100 000 forespørsler / dag * 31 = 15 500 000 forespørsler per måned totalt. Den totale størrelsen på appen vår er omtrent 0,33 MB, som utgjør 0,98 TB utgående trafikk per måned. Minste utførelsestid er 100 ms (noe som vil være nok for vårt fullmektige formål) for vi kan håndtere 10 forespørsler / utførelse sekund.

1x funksjonsapp med 1.550.000 henrettelser med en utførelsestid på 1 hver per måned (hver mindre enn 128 MB minne) for å håndtere forespørslene som går gjennom fullmaktene = 0,17 € / måned

1x Storage Generell formål V2 Block Blob Storage-konto med LRS-redundans og hot access-nivå. Kapasitet 1 GB (vi trenger faktisk bare 300 kb, men det er den minste tilgjengelige størrelsen), 100 skriveoperasjoner, 100 listeoperasjoner, 15 500 000 leseoperasjoner og 0,98 TB datainnhenting = 5,64 € / måned

Totalt: 5,81 € / måned.

Oppbevaring

For lagring tar vi bare den samme beregningen enn ovenfor:

1x Storage Generell formål V2 Block Blob Storage-konto med LRS-redundans og hot access-nivå. Kapasitet 1 GB (vi trenger faktisk bare 300 kb, men det er den minste tilgjengelige størrelsen), 100 skriveoperasjoner, 100 listeoperasjoner, 15 500 000 leseoperasjoner og 0,98 TB datainnhenting = 5,64 € / måned

Konklusjon

  • Hosting av et SPA i ren lagring er den klart billigste og mest utøvende måten å løpe på Azure
  • Hosting av et SPA i en funksjonsapp med fullmakter kommer til en minimal ekstra kostnad, men et enormt ytelsesfall. Denne typen rart som jeg skal skalere horisontalt. Jeg vil definitivt gjøre mer research her ...
  • Hosting av SPA i en apptjeneste krever ekstra konfigurasjonsinnsats for å støtte ruting (blir mer komplisert når det kombineres med f.eks API-er)

Det å være vert for SPA i lagring bør være en ikke-brainer for dev-, test- og iscenesettelsessituasjoner, da det er raskt å konfigurere og i de fleste tilfeller til og med gratis for disse scenariene. Jeg fant ingen ulemper ennå, så vil dykke litt dypere og se om vi også kan bruke det i produksjonen.

Gi gjerne tilbakemelding.