Zephyrnet-logo

CloudFront instellen om uw web-app te hosten

Datum:

In mijn laatste artikel, hebben we besproken hoe u een web-app kunt opzetten die brokken en bundels CSS en JavaScript van CloudFront bedient. We hebben het geïntegreerd in schroef zodat wanneer de app in een browser wordt uitgevoerd, de gevraagde middelen uit het root-HTML-bestand van de app als CDN uit CloudFront zouden worden gehaald.

Hoewel de edge-caching van CloudFront voordelen biedt, is het bedienen van de resources van uw app vanaf deze meerdere locaties niet zonder kosten. Laten we eens kijken naar een WebPageTest trace van mijn eigen web-app, draaiend met de configuratie van de laatste blogpost.

Let op de grote aansluittijden voor lijnen 2-4. Regel 1 is ons HTML-toegangspunt. Die HTML wordt geparseerd, de browser ziet script- en linktags voor de JavaScript- en CSS-items die zich op het CDN bevinden en vraagt ​​deze op. Hierdoor wordt er een nieuwe verbinding tot stand gebracht wat, zoals je ziet, tijd kost.

Dit bericht laat je zien hoe je dit kunt omzeilen. We zullen doornemen hoe u de . kunt hosten GEHELE web-app op CloudFront en laat CloudFront forward - of "proxy" - niet-cacheeerbare verzoeken voor gegevens, auth, enz. Naar onze onderliggende webserver.

Houd er rekening mee dat dit aanzienlijk meer werk is dan wat we in het vorige artikel hebben gezien, en dat de instructies waarschijnlijk voor u anders zijn op basis van de exacte behoeften van uw web-app, dus uw kilometerstand kan variëren. We gaan DNS-records wijzigen en, afhankelijk van uw web-app, moet u mogelijk enkele cacheheaders toevoegen om te voorkomen dat bepaalde activa ooit in de cache worden opgeslagen. We gaan hier allemaal op in!

Je vraagt ​​je misschien af ​​of de setup die we in het laatste artikel hebben behandeld, zelfs voordelen biedt vanwege wat we hier in dit artikel doen. Zouden we, gezien de lange verbindingstijd, beter af zijn geweest van het CDN af te zien en in plaats daarvan al onze activa van de webserver te bedienen om dat langere wachten te voorkomen? Ik heb dit gemeten met mijn eigen web-app, en de CDN-versie hierboven was inderdaad sneller, maar niet veel. De initiële LCP pagina laden was ongeveer 200-300ms sneller. En onthoud, dat is alleen voor de eerste lading. Als deze verbinding eenmaal tot stand is gebracht, zou edge-caching veel meer waarde moeten toevoegen voor al uw volgende, asynchroon geladen chunks.

Onze DNS instellen

Ons einddoel is om onze hele web-app vanuit CloudFront te bedienen. Dat betekent dat wanneer we ons domein bereiken, we willen dat de resultaten van CloudFront komen in plaats van de webserver waaraan het momenteel is gekoppeld. Dat betekent dat we onze DNS-instellingen moeten aanpassen. Hiervoor gebruiken we AWS Route 53.

ik gebruik mydemo.technology als voorbeeld, dat is een domein dat ik bezit. Ik laat je hier alle stappen zien. Maar tegen de tijd dat u dit leest, heb ik dit domein uit mijn web-app verwijderd. Dus als ik je later echte CNAME-records en dergelijke ga laten zien, zullen die niet langer bestaan.

Ga naar de startpagina van Route 53 en klik op gehoste zones:

Het configuratiescherm van de gehoste zone weergeven in de CloudFront-instellingen.

Klik Gehoste zone maken en voer het domein van de app in:

Let nu op de naamservers die in het volgende scherm worden vermeld. Ze zouden er ongeveer zo uit moeten zien.

We hebben nog niet echt iets bereikt. We hebben AWS verteld dat we willen dat het dit domein voor ons beheert, en AWS heeft ons de naamservers gegeven waar het ons verkeer doorheen zal leiden. Om dit in werking te stellen, moeten we naar de plaats gaan waar ons domein is geregistreerd. Er zou een plaats voor u moeten zijn om uw eigen aangepaste naamservers in te voeren.

Merk op dat mijn domein is geregistreerd bij GoDaddy en dat wordt weerspiegeld in de schermafbeeldingen in dit artikel. De gebruikersinterface, instellingen en opties kunnen verschillen van wat u in uw registrar ziet.

Waarschuwing: Ik raad aan om de oorspronkelijke naamservers en alle DNS-records op te schrijven voordat u wijzigingen aanbrengt. Op die manier heb je, mocht er iets mislukken, alles wat je nodig hebt om terug te gaan naar hoe het was voordat je begon. En zelfs als alles goed werkt, wil je nog steeds andere records opnieuw toevoegen aan Route 53, dwz MX-records, enz.

Een CloudFront-distributie opzetten

Laten we een CloudFront-distributie maken om onze web-app te hosten. We hebben de basis besproken in de laatste post, dus we gaan er meteen mee aan de slag. Een grote verandering ten opzichte van de vorige keer is wat we invoeren voor het oorsprongsdomein. Plaats niet het top-level domein, bijvoorbeeld uw-app.net. Wat u nodig heeft, is het onderliggende domein waar uw app wordt gehost. Als dat Heroku is, voer dan de URL in die Heroku je geeft.

Zorg er vervolgens voor dat u het standaardprotocol wijzigt als u van plan bent deze site via een beveiligde HTTPS-verbinding te gebruiken:

Dit onderdeel is cruciaal. Als uw web-app authenticatie uitvoert, gegevens host of iets anders, zorg er dan voor dat u naast GET ook andere werkwoorden inschakelt. Als u dit deel overslaat, worden alle POST-verzoeken voor authenticatie, het muteren van gegevens, enz. afgewezen en mislukken. Als uw web-app niets anders doet dan activa bedienen en al die dingen worden afgehandeld door externe services, dan is dat uitstekend! Je hebt een geweldige setup en je kunt deze stap overslaan.

We moeten nogal wat wijzigingen aanbrengen in de instellingen van de cachesleutel en oorsprongsverzoeken in vergelijking met de vorige keer:

We moeten een cachebeleid maken met een minimale TTL van 0, dus niet-caching-headers die we terugsturen, worden correct gerespecteerd. Mogelijk wilt u ook alle queryreeksen inschakelen. Ik zag raar gedrag toen meerdere GraphQL-verzoeken samen met verschillende queryreeksen werden verzonden, die werden genegeerd, waardoor al deze verzoeken identiek leken vanuit het perspectief van CloudFront.

Mijn polis zag er uiteindelijk als volgt uit:

Voor een beleid voor oorsprongsverzoeken, indien nodig, moeten we ervoor zorgen dat we queryreeksen en cookies verzenden om zaken als authenticatie en gegevensquery's te laten werken. Voor alle duidelijkheid: dit bepaalt of cookies en queryreeksen van CloudFront naar uw webserver (bijv. Heroku of iets dergelijks) worden verzonden.

De mijne ziet er zo uit:

Ten slotte kunnen we voor het beleid voor responsheaders "CORS With Preflight" selecteren in de lijst. Uiteindelijk zullen uw eerste twee verschillende namen hebben, afhankelijk van hoe u ze instelt. Maar de mijne ziet er zo uit:

Laten we ons domein, wat het ook is, verbinden met deze CloudFront-distributie. Helaas is dit meer werk dan je zou verwachten. We moeten aan AWS bewijzen dat we de eigenaar zijn van het domein, want voor zover Amazon weet, zijn we dat niet. We hebben een gehoste zone gecreëerd in Route 53. En we hebben de naamservers gebruikt die het ons gaf en deze geregistreerd bij GoDaddy (of bij wie je domein ook is geregistreerd). Maar Amazon weet dit nog niet. We moeten Amazon aantonen dat we in feite de DNS voor dit domein beheren.

Eerst vragen we een SSL-certificaat aan.

Laten we vervolgens de certificaatlink aanvragen:

Nu selecteren we de optie om een ​​openbare certificaatoptie aan te vragen:

We moeten het domein opgeven:

En in mijn geval is het certificaat in behandeling:

Dus ik ga erop klikken:

Dit bewijst dat we dit domein bezitten en beheren. Ga in een apart tabblad terug naar Route 53 en open onze gehoste zone:

Nu moeten we het CNAME-record maken. Kopieer het eerste deel voor de Recordnaam. Als de CNAME bijvoorbeeld is _xhyqtrajdkrr.mydemo.technology, zet dan de _xhyqtrajdkrr deel. Voor de Recordwaarde, kopieer de volledige waarde.

Ervan uitgaande dat u de AWS-naamservers hebt geregistreerd bij uw domeinhost, GoDaddy of wie dan ook, zal AWS binnenkort de DNS-vermelding kunnen pingen die het u zojuist heeft gevraagd, het verwachte antwoord zien en uw certificaat valideren.

Het kan even duren voordat de nameservers die u aan het begin hebt ingesteld, zich verspreiden. In theorie kan het tot 72 uur duren, maar voor mij wordt het meestal binnen een uur bijgewerkt.

U zult succes zien op het domein:

…alsook het certificaat:

oef! Bijna klaar. Laten we dit nu allemaal verbinden met onze CloudFront-distributie. We kunnen teruggaan naar het instellingenscherm van CloudFront. Nu, op maat SSL-certificaat, zouden we moeten zien wat we hebben gemaakt (en alle andere die je in het verleden hebt gemaakt):

Laten we vervolgens het hoofddomein van de app toevoegen:

Het enige dat overblijft is om Route 53 te vertellen om ons domein naar deze CloudFront-distributie te leiden. Laten we dus teruggaan naar Route 53 en een ander DNS-record maken.

We moeten een A-record invoeren voor IPv4 en een AAAA-record voor IPv6. Laat voor beide de recordnaam leeg, aangezien we alleen ons topleveldomein registreren en niets anders.

Selecteer het A-recordtype. Geef vervolgens de record op als een alias en wijs de alias vervolgens toe aan de CloudFront-distributie. Dat zou een optie moeten openen om uw CloudFront-distributie te kiezen, en aangezien we het domein eerder bij CloudFront hebben geregistreerd, zou u die distributie moeten zien, en alleen die distributie wanneer u een selectie maakt.

We herhalen exact dezelfde stappen voor het AAAA-recordtype dat we nodig hebben voor IPv6-ondersteuning.

Voer uw web-app uit en zorg ervoor dat deze echt werkt. Het zou moeten!

Dingen om te testen en te verifiëren

OK, hoewel we hier technisch klaar zijn, is de kans groot dat er nog een paar dingen moeten worden gedaan om aan de exacte behoeften van uw web-app te voldoen. Verschillende apps hebben verschillende behoeften en wat ik tot nu toe heb aangetoond, heeft ons door de gemeenschappelijke stappen geleid om dingen door CloudFront te leiden voor betere prestaties. De kans is groot dat er dingen zijn die uniek zijn voor uw app en die meer liefde vereisen. Laat me daarom een ​​paar mogelijke extra items behandelen die u tijdens de installatie kunt tegenkomen.

Zorg er allereerst voor dat alle POST's die je hebt correct naar je herkomst worden verzonden. Ervan uitgaande dat CloudFront correct is geconfigureerd om cookies naar uw oorsprong door te sturen, zou dit al moeten werken, maar het kan geen kwaad om te controleren.

De grotere zorg zijn alle andere GET-verzoeken die naar uw web-app worden verzonden. Standaard worden alle GET-verzoeken die CloudFront ontvangt, indien in de cache opgeslagen, aan uw web-app geleverd met het in de cache opgeslagen antwoord. Dit kan rampzalig zijn. Alle gegevensverzoeken naar REST- of GraphQL-eindpunten die met GET worden verzonden, worden door het CDN in de cache opgeslagen. En als u een servicemedewerker verzendt, wordt die ook in de cache opgeslagen, in plaats van het normale gedrag, waarbij de huidige versie op de achtergrond wordt verzonden en wordt bijgewerkt als er wijzigingen zijn.

Om CloudFront te vertellen niet om bepaalde dingen in de cache te plaatsen, moet u ervoor zorgen dat de "Cache-Control" kop naar "no-cache" . Als je een raamwerk gebruikt, zoals Uitdrukken, kunt u middleware instellen voor uw gegevenstoegang met zoiets als dit:

app.use("/graphql", (req, res, next) => {
  res.set("Cache-Control", "no-cache");
  next();
});
app.use(
  "/graphql",
  expressGraphql({
    schema: executableSchema,
    graphiql: true,
    rootValue: root
  })
); 

Voor zaken als servicemedewerkers kunt u specifieke regels voor die bestanden voor uw statische middleware plaatsen:

app.get("/service-worker.js", express.static(__dirname + "/react/dist", { setHeaders: resp => resp.set("Cache-Control", "no-cache") }));
app.get("/sw-index-bundle.js", express.static(__dirname + "/react/dist", { setHeaders: resp => resp.set("Cache-Control", "no-cache") }));
app.use(express.static(__dirname + "/react/dist", { maxAge: 432000 * 1000 * 10 }));

Enzovoort. Test alles grondig, want er kan zoveel mis gaan. En na elke wijziging die u aanbrengt, moet u een volledige ongeldigverklaring uitvoeren in CloudFront en de cache wissen voordat u uw web-app opnieuw uitvoert om te testen of dingen correct zijn uitgesloten van de cache. Dit doe je vanuit de ongeldigverklaringen tabblad in CloudFront. Open dat en zet /* in voor de waarde, om alles te wissen.

Een werkende CloudFront-implementatie

Nu we alles draaiende hebben, laten we onze tracering opnieuw uitvoeren in WebPageTest:

En zo hebben we voor onze assets geen setup-verbindingen meer zoals we eerder zagen. Voor mijn eigen web-app zag ik een aanzienlijke verbetering van 500 ms in LCP. Dat is een stevige overwinning!


Het hosten van een volledige web-app op een CDN kan het beste van alle werelden bieden. We krijgen edge-caching voor statische bronnen, maar zonder de verbindingskosten. Helaas is deze verbetering niet gratis. Het correct instellen van alle benodigde proxy's is niet helemaal intuïtief, en dan is het nog steeds nodig om cacheheaders in te stellen om te voorkomen dat niet-cacheeerbare verzoeken in de cache van het CDN terechtkomen.

spot_img

Laatste intelligentie

spot_img

Chat met ons

Hallo daar! Hoe kan ik u helpen?