Kaip padaryti bet kurį „NodeJS App“ serverį be serverio

Tikiuosi, kad jums patinka „Serverless“ tiek pat, kiek aš, nes tai yra dar vienas pranešimas šia tema.

Dabar, jei mes kalbame apie paprastą REST API be serverio, jūsų sąranka yra akivaizdi „AWS“: „Lambda + API Gateway“.

Bet kaip su kitomis (mikro) paslaugomis, kurias gali turėti jūsų užpakalinė programa? Žinote, ne pati geriausia idėja sudėti visą programos kodą į vieną monolitinę „AWS Lambda“ funkciją.

Iššūkis

Norime lengvai diegti programų modulius kaip be serverio veikiančias mikro paslaugas, kurios taip pat turi palaikyti ryšį. Pageidautina, kad ryšys tarp tarnybų turėtų būti reguliuojamas kažkokiu ACL.

1 bandymas. API šliuzas

Tai yra pirmoji mintis, kurios kilo man bandant išspręsti problemą: tiesiog atskleiskite visas mikropaslaugas per „API Gateway“. Problema ta, kad sukurtos API yra viešos.

Kodėl tokia problema? Pvz., Mes nenorime, kad atsiskaitymo paslauga būtų rodoma visam pasauliui, net jei prieiga ribojama naudojant tam tikrus leidimus.

Na, jūs galite padaryti API privačią, tačiau saugos politika yra gana ribota:

Galite naudoti API šliuzo išteklių strategijas, kad jūsų API būtų galima saugiai naudoti:
* vartotojai iš nurodytos AWS paskyros
* Nurodyti šaltinio IP adresų diapazonai arba CIDR blokai
* nurodyti virtualūs privatūs debesys (VPC) arba VPC galiniai taškai (bet kurioje paskyroje)

Dėl to sunku kontroliuoti tokių tarnybų ryšius. Vienintelis būdas tai padaryti yra paslaugų įdėjimas į atskirus VPC, per daug darbo.

Bandymas 2. Lambda

Kodėl mes tiesiog nededame visų mikro paslaugų į atskirą „AWS Lambda“? Ar tai išspręs problemą?

Taip, iš tikrųjų tai bus be serverio teikiama mikro tarnyba, ir jūs galėsite naudoti IAM politiką norėdami suderinti prieigą tarp paslaugų, bet ... Tai nėra „lengva“.

Aš žinau, kad šiais laikais tai yra visiškai normalu, kad jūsų dislokavimo vienetas turi mažą funkciją. Ir tuo atveju, kai jūsų paslauga turi daugiau nei 1 baigtį / metodą / funkciją, manoma, kad gerai ją naudoti kaip kelias „Lambdas“.

Aš suprantu jo pranašumus, bet jūs aukojate paprastą priežiūrą ir plėtrą. Be to, man labai nepatinka idėja, kad paslauga turėtų būti įdiegta kaip „Lambda“ funkcijų rinkinys. Įsivaizduokite, kelios atskiros funkcijos, susijusios su sąskaitų išrašymu? Tai nebėra ribotas kontekstas. Nors yra atvejų, kai toks detalumas gali būti naudingas, tačiau tai retas atvejis.

Bandymas 3. Riebi lambda

Ar mes iš tikrųjų galime įdiegti baigčių rinkinį kaip vieną „Lambda“ (žinoma, nenaudodami API šliuzo)?

Jei galėtume tai padaryti, gautume visus ankstesnio varianto pranašumus, tačiau taip pat galėtume pasirinkti savo dislokavimo padalinių detalumą.

Aš noriu, kad ji būtų tokia: kiekviena dislokuotina paslauga turėtų būti paprastas senas JS objektas su metodais. Tai yra gana nereikšminga, jei tarp jūsų objekto ir „AWS Lambda“ pridedate keletą klijų kodo eilučių.

Štai ką aš įgyvendinau: aws-RPC. Šis „nodejs“ modulis atskleidžia „lambdaHandler“ funkciją, kai jūs tiesiog pravažiuojate objektą ir automatiškai ją veikia visi, kas gali pasiekti „Lambda“:

importuoti {lambdaHandler} iš 'aws-rpc';
importuoti {TestServiceImpl} iš './TestServiceImpl';
// tai yra jūsų dislokavimo blokas
// štai ką jūs nurodote kaip „Lambda“ prižiūrėtojo funkciją
Export const handler = lambdaHandler (naujas TestServiceImpl ());

Dabar galite tiesiog dislokuoti „prižiūrėtoją“ kaip „AWS Lambda“. Štai kaip jūs naudojate jo metodus:

importuoti {TestService} iš './TestService';
const klientas = laukti „createClient“  („LambdaName“, „test“);
console.log (laukite kliento.testo ());

Atkreipkite dėmesį, kad norėdami sugeneruoti metodus kliento objekto objektui, turite perduoti visus metodų pavadinimus, kad sukurtumėte „createClient“, kaip mes darėme pavyzdyje.

Tai reikalinga, nes JS neturi jokios runtime informacijos apie „TypeScript“ sąsajas. Galėčiau tai įgyvendinti naudodamas abstrakčias klases, bet man tai nepatinka ¯ \ _ (ツ) _ / ¯.

Premija! Viską galite paleisti vietoje!

Manau, kad labai svarbu, kad jūsų vietos vystymosi aplinka būtų kuo patogesnė. Štai kodėl aš taip pat pridėjau galimybę paleisti paslaugą ir klientą vietoje nieko neįdiegdami į AWS (žr. „RunService“ ir „createClient“ funkcijas). Pavyzdžių galite rasti „GitHub“ saugykloje.

Santrauka

Tai labai lengva pasiklysti teikiant debesų paslaugų teikėjų paslaugas ir sustiprinti jūsų infrastruktūrą.

Aš visada pasirenku patį paprasčiausią ir aiškiausią sprendimą, kokį galiu sugalvoti. Taip pat visada atsiminkite, kad daugelį metodų ir praktikų galima panaudoti iš kitų platformų (riebios „NodeJS Lambda“ idėją įkvėpė vadinamieji „Java“ riebalų indeliai).

Jei jums patiko ši tema, peržiūrėkite ir šias:

  • Jūs turite išmokti sukurti geriausią serverių neturinčią architektūrą
  • Kaip sukurti nemokamą CI / CD vamzdyną be serverio: 3 paprasti pavyzdžiai
  • Kaip lengvai atkartoti „DynamoDB“ regionuose
  • Kaip sukurti daugiaregioninę programą (ir mokėti nemokamai)
  • Padarykite bet kurią „Java Web App“ be serverio

Komentarai, patinkimai ir akcijos yra labai vertinami. Džiaugsmas!