Hogyan lehet bármilyen NodeJS App kiszolgáló nélküli

Remélem, annyira szereti a Serverless-t, mint én, mert ez egy újabb üzenet a témáról.

Ha most egy egyszerű kiszolgáló nélküli REST API-ról beszélünk, akkor a telepítés teljesen nyilvánvaló az AWS-en: Lambda + API Gateway.

De mi lenne más (mikro) szolgáltatásokkal, amelyek az Ön háttérszínvonala rendelkeznek? Tudod, nem az a legjobb ötlet, ha az összes alkalmazáskódot egyetlen monolit AWS Lambda funkcióba helyezi.

A kihívás

Azt akarjuk, hogy az alkalmazásmodulokat kiszolgáló nélküli mikroszolgáltatásokként könnyen telepítsük, amelyeknek szintén kommunikálniuk kell egymással. A szolgáltatások közötti kommunikációt előnyösen valamilyen ACL-nek kell szabályoznia.

1. kísérlet. API átjáró

Ez az első gondolat, amelyre gondoltam, amikor megpróbáltam megoldani a problémát: tegye ki az összes mikroszolgáltatást az API Gateway segítségével. A probléma az, hogy a létrehozott API-k nyilvánosak.

Miért van ez a probléma? Például, nem akarjuk, hogy egy számlázási szolgáltatás az egész világnak ki legyen téve, még akkor is, ha a hozzáférést valamilyen felhatalmazás korlátozza.

Nos, teheti az API-t magántulajdonossá, de a biztonsági házirendek meglehetősen korlátozottak:

Az API átjáró erőforrás-házirendjei lehetővé teszik az API biztonságos meghívását az alábbiak által:
* egy megadott AWS-fiók felhasználói
* megadott forrás IP-címtartományok vagy CIDR-blokkok
* meghatározott virtuális magán felhők (VPC) vagy VPC végpontok (bármely fiókban)

Ez meglehetősen bonyolultvá teszi az ilyen szolgáltatások közötti kommunikáció ellenőrzését. Ennek egyetlen módja a szolgáltatás külön VPC-kbe helyezése, túl sok munka.

Kísérlet 2. Lambda

Miért nem tesszük minden mikroszolgáltatást külön AWS Lambda-ba? Meg fogja oldani a problémát?

Igen, valójában kiszolgáló nélküli mikroszolgáltatás lesz, és az IAM-házirendekkel képes lesz kiszolgálni a hozzáféréseket a szolgáltatások között, de… ez nem „egyszerű”.

Tudom, hogy manapság ez teljesen normális, ha egy apró funkcióval rendelkezik, mint a telepítési egység. És abban az esetben, ha a szolgáltatásnak egynél több végpontja / módszere / funkciója van, rendben van, ha több Lambda-ként telepíti azt.

Megértem ennek előnyeit, de feláldozza a karbantartás és fejlesztés egyszerűségét. Ezenkívül nem nagyon szeretem azt a gondolatot, hogy egy szolgáltatást a Lambda funkcióinak halmazaként telepítsünk. Képzelje el, hogy több különálló funkció van a számlázással kapcsolatban? Ez már nem korlátozott kontextus. Noha vannak olyan esetek, amikor az ilyen részletesség hasznos lehet, de ez ritka eset.

3. kísérlet. Kövér Lambda

Lehetséges-e a végpontok halmazát egyetlen Lambda-ként telepíteni (természetesen az API átjáró használata nélkül)?

Ha ezt megtennénk, akkor az előző lehetőség minden előnyeit megszerezzük, de ki is választhatjuk telepítési egységeink részletességét.

A következőképpen szeretném: minden telepíthető szolgáltatásnak egyszerű, egyszerű JS objektumnak kell lennie módszerekkel. Ezt nagyon triviális elérni, ha néhány sort ragasztó kódot adunk az objektum és az AWS Lambda közé.

Itt van a megvalósításom: aws-rpc. Ez a nodejs modul lefedi a lambdaHandler funkciót, ahol csak átad egy tárgyat, és automatikusan kitéve mindenki számára, aki hozzáfér a Lambda-hoz:

{lambdaHandler} importálása az 'aws-rpc' -ből;
{TestServiceImpl} importálása a './TestServiceImpl' fájlból;
// ez a telepítési egység
// ezt határozod meg Lambda kezelő funkcióként
export const kezelő = lambdaHandler (új TestServiceImpl ());

Most már csak telepítheti a „kezelőt” AWS Lambda néven. Így hívhatja fel a módszereit:

importáljon {TestService} -et a './TestService' -ből;
const kliens = várjon createClient  ("LambdaName", "test");
console.log (várjon az client.test ());

Felhívjuk figyelmét, hogy ahhoz, hogy módszereket tudjon generálni az ügyfél-csonk objektumhoz, az összes metódusnevet át kell adnia a createClient-hez, ahogy a példában tettük.

Erre azért van szükség, mert a JS-nek nincs futási idejű információja a TypeScript interfészekről. Absztrakt osztályok segítségével tudtam megvalósítani, de ¯ \ _ (ツ) _ / / nem tetszik.

Bónusz! Az egészet helyben futtathatja!

Úgy gondolom, hogy nagyon fontos, hogy a helyi fejlesztési környezet a lehető legkényelmesebb legyen. Ez az oka annak, hogy a szolgáltatást és az ügyfelet lokálisan is futtatom anélkül, hogy bármit telepítenék az AWS-re (lásd a runService és a createClient függvényeket). A példákat lásd a GitHub tárházában.

összefoglalás

Ez nagyon könnyű eltévedni a felhő-szolgáltatók által nyújtott szolgáltatásokban, és megjavítani az infrastruktúráját.

Mindig a legegyszerűbb és legmeghatározóbb megoldást választom, amire gondolok. Ne felejtsd el továbbá, hogy sok technikát és gyakorlatot más platformon is felhasználhatnak (a zsíros NodeJS Lambda ötletét a Java világ úgynevezett zsírsüvegei inspirálják).

Ha tetszett ez a téma, nézd meg ezeket is:

  • Meg kell tanulnia, hogyan lehet a legjobb kiszolgáló nélküli architektúrát készíteni
  • Ingyenes kiszolgáló nélküli CI / CD csővezeték létrehozása: 3 egyszerű példa
  • A DynamoDB egyszerű replikálása a régiók között
  • Hogyan készíthető többrétegű alkalmazás (és nulla fizetés)
  • Legyen bármilyen Java Web App kiszolgáló nélküli

Nagyon értékelik a megjegyzéseket, kedveléseket és megosztásokat. Egészségére!