Sisältötoimitusverkot (CDN), kuten Amazon CloudFront olivat viime aikoihin saakka suhteellisen yksinkertainen osa verkkoinfrastruktuuria. Perinteisesti heidän ympärilleen suunniteltiin verkkosovelluksia, jotka käsittelivät niitä enimmäkseen passiivisena välimuistina aktiivisen komponentin sijaan.
[sähköposti suojattu] ja vastaavat tekniikat ovat muuttaneet kaikkea tätä ja avanneet kokonaisen mahdollisuuksien maailman tuomalla uuden logiikkakerroksen verkkosovelluksen ja sen käyttäjien välille. Saatavana vuoden 2017 puolivälistä lähtien, [sähköposti suojattu] on AWS: n uusi ominaisuus, joka esittelee koodin suorittamisen Lambdas-muodossa suoraan CloudFrontin reunapalvelimille.
Yksi uusista mahdollisuuksista [sähköposti suojattu] offers on puhdas ratkaisu palvelinpuolen A / B-testaukseen. A / B-testaus on yleinen tapa testata verkkosivuston useiden muunnelmien suorituskykyä näyttämällä ne samanaikaisesti verkkosivuston yleisön eri segmenteille.
A / B-testauksen tärkein tekninen haaste on segmentoida saapuva liikenne oikein vaikuttamatta kokeilun tietojen laatuun tai itse verkkosivustoon millään tavalla.
Sen toteuttamiseen on kaksi pääreittiä: asiakkaan puolella ja palvelimen puolella .
Tässä mielessä saatat ihmetellä, miksi kaikki eivät yksinkertaisesti käytä palvelinpuolen A / B-testausta. Valitettavasti palvelinpuolen lähestymistapaa ei ole niin helppo toteuttaa kuin asiakaspuolella, ja kokeilun asettaminen vaatii usein jonkinlaista puuttumista palvelinpuolen koodiin tai palvelimen kokoonpanoon.
Asiat mutkistavat entisestään, että moderneja verkkosovelluksia, kuten SPA-alueita, tarjoillaan usein staattisen koodin nippuina suoraan S3-ämpäristä ilman edes verkkopalvelinta. Silloinkin kun verkkopalvelin on mukana, ei usein ole mahdollista muuttaa palvelinpuolen logiikkaa A / B-testin asettamiseksi. CDN: n läsnäolo muodostaa vielä yhden esteen, koska välimuisti voi vaikuttaa segmenttien kooihin tai päinvastoin, tällainen liikenteen segmentointi voi heikentää CDN: n suorituskykyä.
Mitä [sähköposti suojattu] tarjoukset on tapa reitittää käyttäjien pyynnöt kokeilumuunnelmien välillä, ennen kuin ne edes osuvat palvelimiin. A perusesimerkki tämän käyttötapauksen löytyy suoraan AWS-dokumentaatiosta. Vaikka tuotantoympäristö on hyödyllinen todiste konseptista, se tarvitsee todennäköisesti jotain joustavampaa ja vankempaa.
Lisäksi, kun olet työskennellyt vähän [sähköposti suojattu] , huomaat todennäköisesti, että on joitain vivahteita, jotka on otettava huomioon rakennettaessa arkkitehtuuriasi.
Esimerkiksi reunalambdojen käyttöönotto vie aikaa, ja niiden lokit jaetaan AWS-alueille. Ole tietoinen tästä, jos sinun on tarkistettava kokoonpano 502-virheiden välttämiseksi.
Tämä opetusohjelma esittelee AWS-kehittäjät tapaan toteuttaa palvelinpuolen A / B-testaus käyttämällä [sähköposti suojattu] tavalla, jota voidaan käyttää uudelleen kokeiden aikana muuttamatta ja sijoittamatta reunalambdoja. Se perustuu AWS-dokumentaation ja muiden vastaavien opetusohjelmien esimerkin lähestymistapaan, mutta sen sijaan, että itse Lambda-liikenteen allokointisäännöt koodattaisiin kovasti, säännöt haetaan säännöllisesti S3: n kokoonpanotiedostosta, jota voit muuttaa milloin tahansa.
Tämän lähestymistavan perusajatuksena on, että CDN määrittää jokaisen käyttäjän segmentille ja ohjaa käyttäjän sitten siihen liittyvään lähtöasetukseen. CloudFrontin avulla jakelu voi osoittaa joko S3: een tai mukautettuihin lähteisiin, ja tässä lähestymistavassa tuemme molempia.
Segmenttien kartoitus kokeilumuunnelmiin tallennetaan JSON-tiedostoon S3: lla. S3 valitaan tässä yksinkertaisuuden vuoksi, mutta tämä voidaan myös noutaa tietokannasta tai muusta tallennustilasta, johon Lambda-reuna pääsee.
Huomautus: Joitakin rajoituksia on - tarkista artikkeli Ulkoisten tietojen hyödyntäminen[sähköposti suojattu] AWS-blogista saadaksesi lisätietoja.
[sähköposti suojattu] voidaan laukaista neljällä erityyppisellä CloudFront-tapahtumalla:
Tässä tapauksessa käytämme Lambdaa jokaisessa seuraavista kolmesta tapahtumasta:
Jokainen tapahtuma toteuttaa vaiheen seuraavassa prosessissa:
Perustetaan myös kolme S3-ryhmää, joista kaksi sisältää kunkin kokeiluvaihtoehdon sisällön, kun taas kolmas sisältää JSON-tiedoston ja liikenteen kohdennuskartan.
Tätä opetusohjelmaa varten kauhat näyttävät tältä:
Aloitetaan ensin liikenteen jakamiskartasta:
map.json
{ 'segments': [ { 'weight': 0.7, 'host': 'abtesting-ttblog-a.s3.amazonaws.com', 'origin': { 's3': { 'authMethod': 'none', 'domainName': 'abtesting-ttblog-a.s3.amazonaws.com', 'path': '', 'region': 'eu-west-1' } } }, { 'weight': 0.3, 'host': 'abtesting-ttblog-b.s3.amazonaws.com', 'origin': { 's3': { 'authMethod': 'none', 'domainName': 'abtesting-ttblog-b.s3.amazonaws.com', 'path': '', 'region': 'eu-west-1' } } } ] }
Jokaisella segmentillä on liikennepaino, jota käytetään varaamaan vastaava määrä liikennettä. Mukana on myös alkuperäkokoonpano ja isäntä. alkuperän määritysmuoto kuvataan AWS-dokumentaatiossa.
abtesting-lambda-vreq
'use strict'; const aws = require('aws-sdk'); const COOKIE_KEY = 'abtesting-unique-id'; const s3 = new aws.S3({ region: 'eu-west-1' }); const s3Params = { Bucket: 'abtesting-ttblog-map', Key: 'map.json', }; const SEGMENT_MAP_TTL = 3600000; // TTL of 1 hour const fetchSegmentMapFromS3 = async () => { const response = await s3.getObject(s3Params).promise(); return JSON.parse(response.Body.toString('utf-8')); } // Cache the segment map across Lambda invocations let _segmentMap; let _lastFetchedSegmentMap = 0; const fetchSegmentMap = async () => { if (!_segmentMap || (Date.now() - _lastFetchedSegmentMap) > SEGMENT_MAP_TTL) { _segmentMap = await fetchSegmentMapFromS3(); _lastFetchedSegmentMap = Date.now(); } return _segmentMap; } // Just generate a random UUID const getRandomId = () => { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) 0x8); return v.toString(16); ); }; // This function will hash any string (our random UUID in this case) // to a [0, 1) range const hashToInterval = (s) => { let hash = 0, i = 0; while (i { const segmentMap = await fetchSegmentMap(); let weight = 0; for (const segment of segmentMap.segments) { weight += segment.weight; if (p { const request = event.Records[0].cf.request; const headers = request.headers; let uniqueId = getCookie(headers, COOKIE_KEY); if (uniqueId === null) { // This is what happens on the first visit: we'll generate a new // unique ID, then leave it the cookie header for the // viewer response lambda to set permanently later uniqueId = getRandomId(); const cookie = `${COOKIE_KEY}=${uniqueId}`; headers.cookie = headers.cookie || []; headers.cookie.push({ key: 'Cookie', value: cookie }); } // Get a value between 0 and 1 and use it to // resolve the traffic segment const p = hashToInterval(uniqueId); const segment = await getSegment(p); // Pass the origin data as a header to the origin request lambda // The header key below is whitelisted in Cloudfront const headerValue = JSON.stringify({ host: segment.host, origin: segment.origin }); headers['x-abtesting-segment-origin'] = [{ key: 'X-ABTesting-Segment-Origin', value: headerValue }]; callback(null, request); };
Täällä luomme nimenomaisesti yksilöllisen tunnuksen tälle opetusohjelmalle, mutta on melko yleistä, että useimmilla verkkosivustoilla on jokin muu asiakastunnus, jota voidaan käyttää sen sijaan. Tämä poistaisi myös tarpeen katsojan vastaukselle Lambda.
Suorituskyvyn vuoksi liikenteen allokointisäännöt välimuistiin Lambda-kutsujen välillä sen sijaan, että ne noudettaisiin S3: sta jokaisesta pyynnöstä. Tässä esimerkissä asetimme välimuistin TTL: n 1 tunniksi.
Huomaa, että X-ABTesting-Segment-Origin
otsikko on lisättävä CloudFront-luetteloon; muuten se pyyhitään pyynnöstä, ennen kuin se saavuttaa Lambda-lähtöpyynnön.
abtesting-lambda-oreq
'use strict'; const HEADER_KEY = 'x-abtesting-segment-origin'; // Origin Request handler exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; const headers = request.headers; const headerValue = headers[HEADER_KEY] && headers[HEADER_KEY][0] && headers[HEADER_KEY][0].value; if (headerValue) { const segment = JSON.parse(headerValue); headers['host'] = [{ key: 'host', value: segment.host }]; request.origin = segment.origin; } callback(null, request); };
Alkuperäpyyntö Lambda on melko yksinkertainen. Lähdekokoonpano ja isäntä luetaan X-ABTesting-Origin
otsikko, joka luotiin edellisessä vaiheessa ja syötettiin pyyntöön. Tämä ohjeistaa CloudFrontia reitittämään pyynnön vastaavaan lähtöpaikkaan, jos välimuisti epäonnistuu.
abtesting-lambda-vres
'use strict'; const COOKIE_KEY = 'abtesting-unique-id'; const getCookie = (headers, cookieKey) => { if (headers.cookie) { for (let cookieHeader of headers.cookie) { const cookies = cookieHeader.value.split(';'); for (let cookie of cookies) { const [key, val] = cookie.split('='); if (key === cookieKey) { return val; } } } } return null; } const setCookie = function (response, cookie) { console.log(`Setting cookie ${cookie}`); response.headers['set-cookie'] = response.headers['set-cookie'] || []; response.headers['set-cookie'] = [{ key: 'Set-Cookie', value: cookie }]; } exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; const headers = request.headers; const response = event.Records[0].cf.response; const cookieVal = getCookie(headers, COOKIE_KEY); if (cookieVal != null) { setCookie(response, `${COOKIE_KEY}=${cookieVal}`); callback(null, response); return; } console.log(`no ${COOKIE_KEY} cookie`); callback(null, response); }
Lopuksi katsojan vastaus Lambda on vastuussa luodun yksilöllisen ID-evästeen palauttamisesta Set-Cookie
otsikko. Kuten edellä mainittiin, jos yksilöllistä asiakastunnusta käytetään jo, tämä Lambda voidaan jättää kokonaan pois.
Itse asiassa, jopa tässä tapauksessa, katsojapyyntö Lambda voi asettaa evästeen uudelleenohjauksella. Tämä voi kuitenkin lisätä jonkin verran viivettä, joten tässä tapauksessa mieluummin se tehdään yhdessä pyynnön ja vastauksen jaksossa.
Koodi löytyy myös osoitteesta GitHub .
Kuten minkä tahansa reunalambdan kohdalla, voit käyttää CloudFront-suunnitelmaa Lambdaa luodessasi. Muussa tapauksessa sinun on luotava mukautettu rooli ja liitettävä Perusasetukset [sähköposti suojattu] Käyttöoikeudet ”-käytäntömalli.
Katsojan Lambda-pyyntöä varten sinun on myös sallittava pääsy S3-ämpäriin, joka sisältää liikenteen allokointitiedoston.
Reunalambdojen asettaminen on jonkin verran erilainen kuin tavallinen Lambda-työnkulku. Napsauta Lamban määrityssivulla Lisää laukaisin ja valitse CloudFront. Tämä avaa pienen valintaikkunan, jonka avulla voit liittää tämän Lambdan CloudFront-jakeluun.
Valitse sopiva tapahtuma kullekin kolmesta lambdasta ja paina 'Ota käyttöön'. Tämä käynnistää toimintokoodin käytön CloudFrontin reunapalvelimille.
Huomautus: Jos haluat muokata reunalambdaa ja sijoittaa sen uudelleen, sinun on ensin julkaistava uusi versio manuaalisesti.
Jotta CloudFront-jakelu pystyy reitittämään liikenteen lähtöpaikkaan, sinun on määritettävä kukin erikseen lähtöpaneelissa.
Ainoa määritysasetus, jota sinun on muutettava, on lisätä se sallittujen luetteloon X-ABTesting-Segment-Origin
otsikko. Sen CloudFront-konsoli , valitse jakelusi ja muuta sitten jakelun asetuksia painamalla muokkaa.
Sen Muokkaa käyttäytymistä sivulla Sallittujen luettelo avattavasta valikosta Välimuisti valittujen pyyntöotsikkojen perusteella vaihtoehto ja lisää mukautettu X-ABTesting-Segment-Origin otsikko luetteloon:
Jos olet ottanut käyttöön reunalambdat edellisessä osassa kuvatulla tavalla, ne on jo liitettävä jakeluosi ja lueteltava Muokkaa käyttäytymistä sivu.
Palvelinpuolen A / B-testaus voi olla haastavaa toteuttaa asianmukaisesti korkean liikenteen verkkosivustoille, jotka on asennettu CDN-palveluiden, kuten CloudFrontin, taakse. Tässä artikkelissa osoitimme kuinka [sähköposti suojattu] voidaan käyttää uutena ratkaisuna tähän ongelmaan piilottamalla toteutuksen yksityiskohdat itse CDN: ään ja samalla tarjoamalla puhdas ja luotettava ratkaisu A / B-kokeiden suorittamiseen.
Kuitenkin, [sähköposti suojattu] on muutama haittapuoli. Tärkeintä on, että nämä CloudFront-tapahtumien väliset Lambda-lisätoimenpiteet voivat lisätä sekä viiveitä että kustannuksia, joten niiden vaikutus CloudFront-jakeluun tulisi mitata ensin.
Lisäksi, [sähköposti suojattu] on suhteellisen uusi ja edelleen kehittyvä AWS-ominaisuus, joten luonnollisesti se tuntuu silti hieman karkealta reunojen ympärillä. Konservatiivisemmat käyttäjät saattavat silti haluta odottaa jonkin aikaa, ennen kuin sijoittavat sen infrastruktuurinsa kriittiseen pisteeseen.
Siitä huolimatta sen tarjoamat ainutlaatuiset ratkaisut tekevät siitä välttämättömän ominaisuuden CDN: ssä, joten ei ole kohtuutonta odottaa, että se otetaan käyttöön tulevaisuudessa paljon laajemmin.
[sähköposti suojattu] on CloudFront-ominaisuus, jonka avulla voit suorittaa mukautetun koodin vastauksena CloudFront-tapahtumiin AWS Lambda -toimintojen muodossa, jotka suoritetaan lähellä CloudFrontin reunapalvelimia. Näitä toimintoja voidaan käyttää CloudFrontin käyttäytymisen muokkaamiseen missä tahansa pyynnön ja vastauksen jaksossa.
[sähköposti suojattu] käyttää standardeja AWS Lambda -toimintoja, jotka on liitetty CloudFront-tapahtuman laukaisimiin, jotka vastaavat neljää mahdollista vaihetta, joihin CloudFront voi kirjoittaa vastatessaan HTTP-pyyntöön. Jokaisen laukaistun suorituksen aikana Lambda voi lukea ja muokata pyyntöä tai vastausobjektia ennen sen siirtämistä seuraavaan vaiheeseen.
AWS [sähköposti suojattu] voidaan käyttää päätöksentekoon siitä, miten pyynnöt tulisi käsitellä ennen kuin ne saapuvat CloudFront-alkuperään. Suosittu käyttötapaus on alkuperän valinta A / B-testausta varten, mutta sitä voidaan käyttää samalla tavalla tarjoamaan mukautettua sisältöä, joka on optimoitu tietylle laitetyypille tai käyttäjäalueelle. Muita käyttötapauksia ovat käyttäjän todennus CloudFrontin kautta (esim. Käyttäjän tunnistetietojen tarkistaminen staattisia resursseja palvellessa) ja jotkin hienotyyppiset välimuistin optimoinnin muodot.
Kirjoitushetkellä ei ole mitään vastaavaa [sähköposti suojattu] joko Microsoft Azuressa tai Google Cloud Platformissa. Nykyinen kilpaileva vaihtoehto on CloudFlare's Workers -ominaisuus, jonka pitäisi periaatteessa mahdollistaa samanlaisen ratkaisun toteuttaminen A / B-testauksessa. Tämä saattaa kuitenkin muuttua pian, koska molemmat pilvipalvelut saattavat alkaa tarjota jotain vastaavaa tulevaisuudessa.
Koska CloudFrontia veloitetaan äänenvoimakkuuden perusteella, kaikilla asianmukaisesti toteutetuilla A / B-testeillä ei pitäisi olla merkittävää vaikutusta CDN-liikenteeseen. [sähköposti suojattu] kutsut laskutetaan kuitenkin erikseen samalla tavalla kuin AWS Lambda -toiminnot - ts. kutsujen määrän ja kunkin Lambda-suorituksen kokonaiskeston perusteella.