NodeJS 앱을 서버리스로 만드는 방법

이 주제에 대한 또 다른 게시물이기 때문에 Serverless를 좋아하는만큼 많이 바랍니다.

이제 간단한 서버리스 REST API에 대해 이야기한다면 AWS에서 Lambda + API Gateway의 설정이 매우 분명합니다.

그러나 백엔드에있는 다른 (마이크로) 서비스는 어떻습니까? 모든 애플리케이션 코드를 단일 모 놀리 식 AWS Lambda 함수에 넣는 것이 가장 좋은 방법은 아닙니다.

도전

우리는 응용 프로그램 모듈을 서버리스 마이크로 서비스로 쉽게 배포하고 서로 통신해야합니다. 바람직하게는, 서비스들 간의 통신은 어떤 종류의 ACL에 의해 규제되어야한다.

시도 1. API 게이트웨이

이것은 문제를 해결하려고 할 때 처음으로 생각한 것입니다. API 게이트웨이를 통해 모든 마이크로 서비스를 노출하기 만하면됩니다. 문제는 ... 작성된 API가 공개입니다.

왜 이것이 문제입니까? 예를 들어 어떤 종류의 인증을 사용하여 액세스가 제한 되더라도 전 세계에 결제 서비스가 노출되는 것을 원하지 않습니다.

글쎄, 당신은 API를 비공개로 만들 수 있지만 보안 정책은 매우 제한적입니다.

API Gateway 리소스 정책을 사용하여 다음을 통해 API를 안전하게 호출 할 수 있습니다.
* 지정된 AWS 계정의 사용자
* 지정된 소스 IP 주소 범위 또는 CIDR 블록
* 지정된 가상 프라이빗 클라우드 (VPC) 또는 VPC 엔드 포인트 (모든 계정)

따라서 이러한 서비스 간의 통신을 제어하기가 매우 어렵습니다. 이 작업을 수행하는 유일한 방법은 서비스를 별도의 VPC에 배치하는 것입니다.

시도 2. 람다

왜 모든 마이크로 서비스를 별도의 AWS Lambda에 넣지 않습니까? 문제가 해결됩니까?

그렇습니다. 실제로 서버리스 마이크로 서비스가 될 것입니다. IAM 정책을 사용하여 서비스 간 액세스를 조정할 수는 있지만“쉬운”것은 아닙니다.

나는 이것이 당신의 배포 단위로 작은 기능을하는 것이 오늘날 매우 정상적인 것을 알고 있습니다. 또한 서비스에 엔드 포인트 / 방법 / 기능이 둘 이상인 경우 여러 Lambdas로 배포해도 괜찮습니다.

나는 그것의 장점을 이해하지만 유지 관리 및 개발의 용이성을 희생합니다. 또한 서비스를 Lambda 함수 세트로 배포한다는 아이디어가 마음에 들지 않습니다. 과금을 처리하는 여러 개의 개별 기능이 있다고 상상해보십시오. 더 이상 경계가 아닙니다. 이러한 세분성이 유용한 경우가 있지만 드문 경우입니다.

시도 3. 뚱뚱한 람다

실제로 API 게이트웨이를 사용하지 않고 엔드 포인트 집합을 단일 Lambda로 배포 할 수 있습니까?

이 작업을 수행 할 수 있으면 이전 옵션의 모든 이점을 얻을 수 있지만 배포 단위의 세분성을 선택할 수도 있습니다.

내가 원하는 방식은 다음과 같습니다. 배포 가능한 각 서비스는 메서드가있는 단순하고 오래된 JS 객체 여야합니다. 객체와 AWS Lambda 사이에 몇 줄의 접착제 코드를 추가하면 달성하기가 쉽지 않습니다.

다음은 그것을 구현 한 것입니다 : aws-rpc. 이 nodejs 모듈은 객체를 전달하는 lambdaHandler 함수를 노출하며 Lambda에 액세스 할 수있는 모든 사람에게 자동으로 노출됩니다.

'aws-rpc'에서 {lambdaHandler} 가져 오기;
'./TestServiceImpl'에서 {TestServiceImpl} 가져 오기;
// 배포 단위입니다
// 이것은 Lambda의 핸들러 함수로 지정한 것입니다.
내보내기 const 핸들러 = lambdaHandler (new TestServiceImpl ());

이제 "handler"를 AWS Lambda로 배포 할 수 있습니다. 메소드를 호출하는 방법은 다음과 같습니다.

'./TestService'에서 {TestService} 가져 오기;
const client = await createClient  ( "LambdaName", "test");
console.log (await client.test ());

클라이언트 스텁 객체에 대한 메소드를 생성하려면 예제에서와 같이 모든 메소드 이름을 createClient에 전달해야합니다.

JS에는 TypeScript 인터페이스에 대한 런타임 정보가 없기 때문에 필수입니다. 추상 클래스를 사용하여 구현할 수 있지만 ¯ \ _ (ツ) _ / ¯가 마음에 들지 않습니다.

보너스! 로컬에서 모두 실행할 수 있습니다!

지역 개발 환경을 가능한 한 편안하게 유지하는 것이 매우 중요하다고 생각합니다. 이것이 바로 AWS에 아무것도 배포하지 않고 서비스와 클라이언트를 로컬로 실행할 수있는 기능을 추가 한 이유입니다 (runService 및 createClient 함수 참조). 예를 들어, GitHub의 저장소를 참조하십시오.

개요

이는 클라우드 제공 업체가 제공하는 서비스에서 손실되기 쉽고 인프라를 과도하게 엔지니어링합니다.

나는 항상 내가 생각할 수있는 가장 단순하고 명확한 솔루션을 선택합니다. 또한 많은 기술과 사례를 다른 플랫폼에서 재사용 할 수 있다는 점을 항상 기억하십시오 (팻 NodeJS Lambda의 아이디어는 Java 세계의 소위 지방 병에서 영감을 얻음).

이 주제가 마음에 들면 다음 사항도 확인하십시오.

  • 최고의 서버리스 아키텍처를 만드는 방법을 배워야합니다
  • 무료 서버리스 CI / CD 파이프 라인을 만드는 방법 : 3 가지 쉬운 예
  • 여러 지역에서 DynamoDB를 쉽게 복제하는 방법
  • 다국적 신청 방법 (및 Pay Zero)
  • 모든 Java Web App을 서버리스로 만들기

의견, 좋아요 및 공유는 높이 평가됩니다. 건배!