programming/MSA
Serverelss Framework
yhsim98
2022. 9. 19. 03:32
Serverless
클라우드 제공업체가 클라우드 인프라와 애플리케이션 스케일링을 모두 관리
표준 서비스 인프라(laaS) 클라우드 컴퓨팅 모델에서 사용자는 용량 단위를 사전에 구매하게 된다.
상시 가동 중인 서버 구성 요소에 대한 비용을 지불하고, 수요가 많을 때 스케일 업이나 다운하는 것 역시 사용자의 책임. 애플리케이션을 구동하기 위해 필요한 클라우드 인프라는 애플리케이션이 사용되지 않을 때도 활성화된 상태이다.
반면, 서버리스 아키텍처에서는 애플리케이션이 필요한 경우에만 시작.
이벤트가 구동을 위한 애플리케이션 코드를 트리커하면 퍼블릭 클라우드 공급업체가 신속하게 해당 코드에 대한 리소스를 할당. 코드 실행이 종료되면 비용도 청구되지 않는다.
비용과 효율성 외에도, 서버리스는 애플리케이션 스케일링 및 서버 프로비저닝(과 같은 부분에서도 개발자의 부담을 덜어준다.
비동기식 stateless 애플리케이션에서 이상적
프로비저닝
- 프로비저닝(provisioning)은 사용자의 요구에 맞게 시스템 자원을 할당, 배치, 배포해 두었다가 필요 시 시스템을 즉시 사용할 수 있는 상태로 미리 준비해 두는 것을 말한다
Infrastructure as a Service(IaaS)
- 클라우드 서비스의 종류
- 개발사에 제공되는 물리적 자원을 가상화
- 컴퓨팅 리소스를 가상화하여 제공하는 것
Platform as a Service(PaaS)
- 개발사에 제공되는 플랫폼을 가상화
Software as a Service(SaaS)
- 고객에게 제공되는 소프트웨어를 가상화
- 인터넷을 통하여 응용프로그램 제공?
장점
- 서버리스 컴퓨팅은 개발자 생산성을 높이고 운영 비용을 줄일 수 있다.
- 인프라를 명시적으로 설명할 필요를 줄여줌으로써 DevOps 도입을 지원
- BaaS의 모든 구성 요소를 통합해 애플리케이션 개발을 간소화
- 항상 자체 서버를 실행하고 관리하는 대신 필요한 만큼 클라우드 기반 컴퓨팅 시간에 대해 비용을 지불
단점
- 자체 서버를 실행하지 않거나 자체 서버측 로직을 제어하지 않는 데 따른 단점
- 클라우드 제공업체는 자사 구성 요소가 상호작용하는 방법을 엄격히 제한할 수 있어, 사용자 시스템의 유연성과 커스터마이징 수준에 영향을 준다
- 특정 벤더에 종속성을 가진다
Serverless Framework
- 개발, 배포, 트러블슈팅, 보안관리를 적은 비용으로 할 수 있도록 도와주는 프레임워크
- CLI와 hosted dashboard 로 구성되어 있으며, 이것을 통해 완전한 서버리스 애플리케이션 라이프사이클 관리를 제공해 준다
- 정리하자면, 환경을 배포하고 운영하기 위한 도구
- AWS 람다 사용하여 함수를 작성하고, AWS API Gateway 띄우고 SNS, Dynamo DB 설정하는 등 여러 설정 등을 대신해 준다
Get Started
Node와 NPM이 설치되어 있어야 합니다
- 해당 명령어를 통해 설치를 확인할 수 있습니다
# 각 버젼 확인 npm -v node -v
# serverless 프레임워크 설치, sudo로 실행해야 합니다
npm install -g serverless
# node.js 용 serverless template을 다운로드합니다
# 기존 프로젝트에 serverless.yml 생성해서 해도 가능합니다
# spring boot의 경우에도 루트 경로에 serverless.yml 생성하면 됩니다
serverless --template-url=https://github.com/serverless/examples/tree/v3/aws-node-http-api
# Move into the newly created directory
cd your-service-name
- 생성된 serverless 프로젝트는 serverless.yml 파일을 포함하고 있다
- 이 파일은 AWS 에 어떤 것이 배포될 것인지 정의하는 설정파일
- 함수나 이벤트 자원 등등
- 자세한 설정에 대한 정보는
- https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml 참고
# 서비스 이름
service: serverlessNodeJS
# 사용할 서버리스 프레임워크 버젼
frameworkVersion: '3'
# The cloud provider that we are going to use and the runtime environment.
provider:
name: aws
# 배포할 스테이지 (default: dev)
stage: dev
# 배포할 리전, 참고로 서울은 serverless dashboard가 지원 안함 (default: us-east-1)
region: us-east-1
# The AWS profile to use to deploy (default: "default" profile)
profile: production
# Use a custom name for the CloudFormation stack
stackName: custom-stack-name
# Optional CloudFormation tags to apply to APIs and functions
tags:
foo: bar
baz: qux
# Optional CloudFormation tags to apply to the stack
stackTags:
key: value
# Method used for CloudFormation deployments: 'changesets' or 'direct' (default: changesets)
# See <https://www.serverless.com/framework/docs/providers/aws/guide/deploying#deployment-method>
deploymentMethod: direct
# List of existing Amazon SNS topics in the same region where notifications about stack events are sent.
notificationArns:
- 'arn:aws:sns:us-east-1:XXXXXX:mytopic'
stackParameters:
- ParameterKey: 'Keyname'
ParameterValue: 'Value'
# Disable automatic rollback by CloudFormation on failure. To be used for non-production environments.
disableRollback: true
rollbackConfiguration:
MonitoringTimeInMinutes: 20
RollbackTriggers:
- Arn: arn:aws:cloudwatch:us-east-1:000000000000:alarm:health
Type: AWS::CloudWatch::Alarm
- Arn: arn:aws:cloudwatch:us-east-1:000000000000:alarm:latency
Type: AWS::CloudWatch::Alarm
tracing:
# Can only be true if API Gateway is inside a stack.
apiGateway: true
# Optional, can be true (true equals 'Active'), 'Active' or 'PassThrough'
lambda: true
functions:
# AWS 람다함수 이름
hello:
# 실행할 함수의 위치와 함수 이름
handler: handler.hello
# 발생할 이벤트
events:
# API 타입
- httpApi:
# URL 경로
path:
method: get
Amazon API Gateway
AWS Lambda
node.js로 serverless 개발 시작하기
- 위 템플릿에서 따로 설정할 것은 없습니다
- 예시코드
- https://github.com/yhsim98/node-serverless-starter
spring-boot로 serverless 개발 시작하기
- 예시코드
- https://github.com/yhsim98/spring-serverless-start
- 참고 레퍼런스
- https://github.com/awslabs/aws-serverless-java-container/wiki/Quick-start---Spring-Boot2
- spring-boot 2.2.x 이상 버젼을 권장합니다
- build.gradle
# 필요한 dependency
implementation group: 'com.amazonaws.serverless', name: 'aws-serverless-java-container-springboot2', version: '1.6'
implementation group: 'com.amazonaws', name: 'aws-lambda-java-events', version: '3.10.0' // For deserialize AWS events
# 빌드 설정
task buildZipFull(type: Zip) {
baseName = "springboot-serverless-test"
from compileJava
from processResources
into('lib') {
from(configurations.compileClasspath) {
exclude 'tomcat-embed-*'
}
}
}
build.dependsOn buildZipFull
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
- handelr를 생성해야 합니다
- AWS Lambda의 요청을 spring message 로 convert 해주고, API Gateway의 이벤트를 Spring boot의 controller로 넘겨주는 역할을 수행합니다
public class StreamLambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(SpringbootServerlessTestApplication.class);
// If you are using HTTP APIs with the version 2.0 of the proxy model, use the getHttpApiV2ProxyHandler
// method: handler = SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(Application.class);
} catch (ContainerInitializationException e) {
// if we fail here. We re-throw the exception to force another cold start
e.printStackTrace();
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}
@Override
@SuppressWarnings("unchecked")
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
throws IOException {
handler.proxyStream(inputStream, outputStream, context);
}
}
- serverless.yml
provider:
name: aws
runtime: java11
timeout: 15
# 배포할 빌드 파일 경로
package:
artifact: build/distributions/springboot-serverless-test-0.0.1-SNAPSHOT.zip
# 함수 설정
functions:
getPoint:
# 핸들러 경로
handler: com.example.serverless.StreamLambdaHandler::handleRequest
events:
- http:
path: point
method: get
cors: true