AWS Lambda를 사용한 서비스 지향 아키텍처: 단계별 자습서
게시 됨: 2022-03-11웹 애플리케이션을 구축할 때, 일단 커밋하면 미래에 애플리케이션을 돕거나 방해할 수 있는 많은 선택을 해야 합니다. 언어, 프레임워크, 호스팅 및 데이터베이스와 같은 선택이 중요합니다.
그러한 선택 중 하나는 SOA(서비스 지향 아키텍처)를 사용하여 서비스 기반 응용 프로그램을 만들 것인지 아니면 기존의 모놀리식 응용 프로그램을 만들 것인지입니다. 이는 신생 기업, 규모 확장 및 엔터프라이즈 기업 모두에 영향을 미치는 일반적인 아키텍처 결정입니다.
Service Oriented Architecture는 구글, 페이스북, 트위터, 인스타그램, 우버와 같은 수많은 유명 유니콘과 일류 기업에서 사용하고 있습니다. 겉보기에는 이 아키텍처 패턴이 대기업에 적합하지만 귀사에 적합할까요?
이 기사에서는 서비스 지향 아키텍처라는 주제를 소개하고 AWS Lambda를 Python과 함께 사용하여 확장 가능하고 비용 효율적인 서비스를 쉽게 구축할 수 있는 방법을 소개합니다. 이러한 아이디어를 보여주기 위해 Python, AWS Lambda, Amazon S3 및 기타 몇 가지 관련 도구와 서비스를 사용하여 간단한 이미지 업로드 및 크기 조정 서비스를 구축합니다.
서비스 지향 아키텍처란 무엇입니까?
서비스 지향 아키텍처(SOA)는 새로운 것이 아니며 수십 년 전에 뿌리를 두고 있습니다. 최근 몇 년 동안 웹 페이싱 애플리케이션에 많은 이점을 제공함으로써 패턴으로서의 인기가 높아지고 있습니다.
본질적으로 SOA는 하나의 큰 응용 프로그램을 여러 개의 통신하는 작은 응용 프로그램으로 추상화한 것입니다. 이는 분리, 관심사 분리 및 단일 책임 아키텍처와 같은 소프트웨어 엔지니어링의 몇 가지 모범 사례를 따릅니다.
SOA의 구현은 세분성 측면에서 다양합니다. 즉, "마이크로서비스" 아키텍처라고 하는 수십 또는 수백 개의 소규모 애플리케이션에 이르기까지 광범위한 기능 영역을 다루는 극소수의 서비스에 이르기까지 다양합니다. 세분성 수준에 관계없이 SOA 실무자들 사이에서 일반적으로 동의하는 것은 그것이 결코 공짜 점심이 아니라는 것입니다. 소프트웨어 엔지니어링의 많은 우수 사례와 마찬가지로 추가 계획, 개발 및 테스트가 필요한 투자입니다.
AWS 람다란 무엇입니까?
AWS Lambda는 Amazon Web Services 플랫폼에서 제공하는 서비스입니다. AWS Lambda를 사용하면 Amazon에서 관리하는 온디맨드 컨테이너에서 실행할 코드를 업로드할 수 있습니다. AWS Lambda는 코드를 실행하기 위한 서버의 프로비저닝 및 관리를 관리하므로 사용자는 실행할 패키지된 코드 세트와 서버가 실행되는 컨텍스트를 정의하기 위한 몇 가지 구성 옵션만 있으면 됩니다. 이러한 관리형 애플리케이션을 Lambda 함수라고 합니다.
AWS Lambda에는 두 가지 주요 작동 모드가 있습니다.
비동기/이벤트 기반:
Lambda 함수는 비동기 모드에서 이벤트에 대한 응답으로 실행할 수 있습니다. S3, SNS 등과 같은 모든 이벤트 소스는 차단되지 않으며 Lambda 함수는 일부 이벤트 체인에 대한 처리 파이프라인을 설정하는 등 다양한 방식으로 이를 활용할 수 있습니다. 많은 정보 소스가 있으며 소스에 따라 이벤트는 이벤트 소스에서 Lambda 함수로 푸시되거나 AWS Lambda에서 이벤트에 대해 폴링됩니다.
동기/요청->응답:
응답을 동기적으로 반환해야 하는 애플리케이션의 경우 Lambda를 동기 모드로 실행할 수 있습니다. 일반적으로 이는 API Gateway라는 서비스와 함께 사용하여 AWS Lambda에서 최종 사용자에게 HTTP 응답을 반환하지만, Lambda 함수는 AWS Lambda에 대한 직접 호출을 통해 동기식으로 호출할 수도 있습니다.
AWS Lambda 함수는 핸들러 작업에 필요한 종속성 외에 핸들러 코드가 포함된 zip 파일로 업로드됩니다. 업로드되면 AWS Lambda는 필요할 때 이 코드를 실행하고 소비자가 필요로 하는 추가 개입 없이 필요할 때 서버 수를 0에서 수천으로 확장합니다.
SOA의 진화로서의 Lambda 함수
기본 SOA는 이 기사의 앞부분에서 설명한 방식으로 애플리케이션에 이점을 주기 위해 코드 기반을 작은 애플리케이션으로 구조화하는 방법입니다. 이로 인해 이러한 응용 프로그램 간의 통신 방법에 중점을 둡니다. 이벤트 기반 SOA(SOA 2.0이라고도 함)를 사용하면 SOA 1.0의 기존 서비스 간 직접 통신뿐만 아니라 변경 사항을 전달하기 위해 아키텍처 전체에 이벤트를 전파할 수 있습니다.
이벤트 기반 아키텍처는 자연스럽게 느슨한 결합과 구성성을 촉진하는 패턴입니다. 이벤트를 생성하고 대응함으로써 서비스를 애드혹으로 추가하여 기존 이벤트에 새로운 기능을 추가할 수 있으며, 여러 이벤트를 구성하여 보다 풍부한 기능을 제공할 수 있습니다.
AWS Lambda는 SOA 2.0 애플리케이션을 쉽게 구축할 수 있는 플랫폼으로 사용할 수 있습니다. Lambda 함수를 트리거하는 방법에는 여러 가지가 있습니다. Amazon SNS의 기존 메시지 대기열 접근 방식에서 Amazon S3에 업로드되는 파일 또는 Amazon SES로 전송되는 이메일에 의해 생성되는 이벤트에 이르기까지.
간단한 이미지 업로드 서비스 구현
AWS 스택을 활용하여 이미지를 업로드하고 검색하는 간단한 애플리케이션을 구축할 것입니다. 이 예제 프로젝트에는 두 개의 람다 함수가 포함됩니다. 하나는 간단한 웹 프론트엔드를 제공하는 데 사용되는 요청->응답 모드에서 실행되고 다른 하나는 업로드된 이미지를 감지하고 크기를 조정합니다.
첫 번째 람다 함수는 업로드된 이미지를 저장할 S3 버킷에서 트리거된 파일 업로드 이벤트에 대한 응답으로 비동기식으로 실행됩니다. 제공된 이미지를 가져와 400x400 이미지에 맞게 크기를 조정합니다.
다른 람다 함수는 HTML 페이지를 제공하여 사용자가 다른 람다 함수로 크기를 조정한 이미지를 볼 수 있는 기능과 이미지를 업로드하기 위한 인터페이스를 모두 제공합니다.
초기 AWS 구성
시작하기 전에 IAM 및 S3와 같은 몇 가지 필요한 AWS 서비스를 구성해야 합니다. 웹 기반 AWS 콘솔을 사용하여 구성됩니다. 그러나 대부분의 구성은 나중에 사용할 AWS 명령줄 유틸리티를 사용하여 수행할 수도 있습니다.
S3 버킷 생성
S3(또는 Simple Storage Service)는 모든 데이터의 안정적이고 비용 효율적인 스토리지를 제공하는 Amazon 객체 저장소 서비스입니다. 업로드할 이미지와 처리한 이미지의 크기가 조정된 버전을 저장하는 데 S3를 사용할 것입니다.
S3 서비스는 AWS 콘솔의 "Storage & Content Delivery" 하위 섹션에 있는 "Services" 드롭다운에서 찾을 수 있습니다. 버킷을 생성할 때 버킷 이름과 지역을 모두 입력하라는 메시지가 표시됩니다. 사용자와 가까운 지역을 선택하면 S3가 대기 시간과 비용, 일부 규제 요인에 대해 최적화할 수 있습니다. 이 예에서는 "US Standard" 지역을 선택합니다. 이 동일한 리전은 나중에 AWS Lambda 함수를 호스팅하는 데 사용됩니다.
S3 버킷 이름은 고유해야 하므로 선택한 이름을 사용하는 경우 고유한 새 이름을 선택해야 합니다.
이 예제 프로젝트에서는 "test-upload" 및 "test-resized"라는 두 개의 스토리지 버킷을 생성합니다. "test-upload" 버킷은 이미지를 업로드하고 업로드된 이미지가 처리 및 크기 조정되기 전에 저장하는 데 사용됩니다. 크기가 조정되면 이미지가 "테스트 크기 조정" 버킷에 저장되고 업로드된 원시 이미지가 제거됩니다.
S3 업로드 권한
기본적으로 S3 권한은 제한적이며 외부 사용자나 관리자가 아닌 사용자도 버킷의 권한이나 객체를 읽고, 쓰고, 업데이트하거나, 삭제할 수 없습니다. 이를 변경하려면 AWS 버킷 권한을 관리할 수 있는 권한이 있는 사용자로 로그인해야 합니다.
AWS 콘솔에 있다고 가정하면 이름으로 버킷을 선택하고 화면 오른쪽 상단의 "속성" 버튼을 클릭하고 축소된 "권한" 섹션을 열어 업로드 버킷에 대한 권한을 볼 수 있습니다.
익명 사용자가 이 버킷에 업로드할 수 있도록 하려면 업로드를 허용하는 특정 권한을 허용하도록 버킷 정책을 편집해야 합니다. 이는 JSON 기반 구성 정책을 통해 수행됩니다. 이러한 종류의 JSON 정책은 IAM 서비스와 함께 AWS 전반에 걸쳐 널리 사용됩니다. "버킷 정책 편집" 버튼을 클릭하면 다음 텍스트를 붙여넣고 "저장"을 클릭하여 공개 이미지 업로드를 허용합니다.
{ "Version": "2008-10-17", "Id": "Policy1346097257207", "Statement": [ { "Sid": "Allow anonymous upload to /", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::test-upload/*" } ] }이 작업을 수행한 후 버킷에 이미지를 업로드하여 버킷 정책이 올바른지 확인할 수 있습니다. 다음 cURL 명령이 트릭을 수행합니다.
curl https://test-upload.s3.amazonaws.com -F 'key=test.jpeg' -F '[email protected]'200 범위 응답이 반환되면 업로드 버킷에 대한 구성이 성공적으로 적용되었음을 알 수 있습니다. 이제 S3 버킷이 (대부분) 구성되어야 합니다. 이미지 업로드 이벤트를 크기 조정 기능 호출에 연결하기 위해 나중에 콘솔에서 이 서비스로 돌아갑니다.
Lambda에 대한 IAM 권한
Lambda 역할은 모두 권한 컨텍스트 내에서 실행되며, 이 경우 IAM 서비스에서 정의한 "역할"입니다. 이 역할은 호출 중에 Lambda 함수가 갖는 모든 권한을 정의합니다. 이 예제 프로젝트의 목적을 위해 두 Lambda 함수 간에 사용할 일반 역할을 생성합니다. 그러나 프로덕션 시나리오에서는 모든 보안 악용이 정의된 권한 컨텍스트로만 격리되도록 권한 정의를 더 세분화하는 것이 좋습니다.
IAM 서비스는 "서비스" 드롭다운의 "보안 및 ID" 하위 섹션에서 찾을 수 있습니다. IAM 서비스는 AWS 서비스 전반에 걸친 액세스를 관리하기 위한 매우 강력한 도구이며, 유사한 도구에 익숙하지 않은 경우 제공되는 인터페이스가 처음에는 다소 압도적일 수 있습니다.
IAM 대시보드 페이지에서 "역할" 하위 섹션은 페이지 왼쪽에서 찾을 수 있습니다. 여기에서 "새 역할 만들기" 버튼을 사용하여 역할의 권한을 정의하는 다단계 마법사를 불러올 수 있습니다. 일반 권한의 이름으로 "lambda_role"을 사용하겠습니다. 이름 정의 페이지에서 계속하면 역할 유형을 선택하는 옵션이 표시됩니다. S3 액세스만 필요하므로 "AWS 서비스 역할"을 클릭하고 선택 상자 내에서 "AWS Lambda"를 선택합니다. 이 역할에 연결할 수 있는 정책 페이지가 표시됩니다. "AmazonS3FullAccess" 정책을 선택하고 다음 단계를 계속하여 생성할 역할을 확인합니다.
생성된 역할의 이름과 ARN(Amazon 리소스 이름)을 기록해 두는 것이 중요합니다. 이는 함수 호출에 사용할 역할을 식별하기 위해 새 Lambda 함수를 생성할 때 사용됩니다.
참고: AWS Lambda는 로깅 서비스인 AWS Cloudwatch에서 함수 호출의 모든 출력을 자동으로 로깅합니다. 프로덕션 환경에 권장되는 이 기능이 필요한 경우 이 역할에 대한 정책에 Cloudwatch 로그 스트림에 대한 쓰기 권한을 추가해야 합니다.
코드!
개요
이제 코딩을 시작할 준비가 되었습니다. 이 시점에서 "awscli" 명령을 설정했다고 가정합니다. 아직 설정하지 않은 경우 https://aws.amazon.com/cli/의 지침에 따라 컴퓨터에서 awscli를 설정할 수 있습니다.
참고: 이 예제에 사용된 코드는 화면 보기를 쉽게 하기 위해 더 짧게 만들어졌습니다. 더 완전한 버전을 보려면 https://github.com/gxx/aws-lambda-python/의 리포지토리를 방문하세요.
먼저 프로젝트의 골격 구조를 설정해 보겠습니다.
aws-lambda-python/ - image_list/ - handler.py - list.html - Makefile - requirements.txt - image_resize/ - handler.py - resize.py - Makefile - requirements.txt - .pydistutils.cfg구조에는 람다 함수 각각에 대해 하나씩 두 개의 하위 디렉터리가 있습니다. 이들 각각에는 공통 handler.py, Makefile 및 requirements.txt 파일이 있습니다. handler.py 파일에는 각 람다 함수 호출 시 호출하는 메서드가 포함되며 함수의 진입점으로 간주될 수 있습니다. 요구 사항.txt 파일에는 종속성 목록이 포함되므로 요구 사항을 쉽게 지정하고 업데이트할 수 있습니다. 마지막으로 Makefile 명령은 awscli와 상호 작용하기 위한 쉬운 메커니즘을 제공하는 데 사용할 것입니다. 이렇게 하면 람다 함수를 만들고 업데이트하는 프로세스가 훨씬 쉬워집니다.
프로젝트 디렉토리의 루트에 .pydistutils.cfg 파일이 있습니다. Homebrew에서 Python으로 작업하는 경우 이 파일이 필요합니다. Lambda 함수를 배포하는 방법(다음 섹션에서 다룸) 때문에 이 파일이 필요합니다. 자세한 내용은 저장소를 참조하세요.
이미지 크기 조정 Lambda 함수
암호
resize_image 함수로 시작하여 Wand==0.4.2 를 requirements.txt에 저장하여 이미지 처리 라이브러리인 Wand 종속성을 고정합니다. 이것은 image_resize 람다 함수에 대한 유일한 종속성이 됩니다. resize.py의 resize_image 함수는 Wand 라이브러리의 이미지 리소스를 처리하고 지정된 너비 및 높이 매개변수에 따라 크기를 조정해야 합니다. 크기가 조정되는 이미지를 유지하기 위해 원본 이미지의 이미지 비율을 유지하면서 지정된 너비와 높이에 맞게 이미지 크기를 줄이는 "최적화" 크기 조정 알고리즘을 사용합니다.
def resize_image(image, resize_width, resize_height): ... original_ratio = image.width / float(image.height) resize_ratio = resize_width / float(resize_height) # We stick to the original ratio here, regardless of what the resize ratio is if original_ratio > resize_ratio: # If width is larger, we base the resize height as a function of the ratio of the width resize_height = int(round(resize_width / original_ratio)) else: # Otherwise, we base the width as a function of the ratio of the height resize_width = int(round(resize_height * original_ratio)) if ((image.width - resize_width) + (image.height - resize_height)) < 0: filter_name = 'mitchell' else: filter_name = 'lanczos2' image.resize(width=resize_width, height=resize_height, filter=filter_name, blur=1) return image 그 과정에서 S3 업로드된 이미지에 의해 생성된 이벤트를 수락하고, resize_image 함수에 전달하고, 크기가 조정된 결과 이미지를 저장하려면 핸들러 함수가 필요합니다.
from __future__ import print_function import boto3 from wand.image import Image from resize import resize_image def handle_resize(event, context): # Obtain the bucket name and key for the event bucket_name = event['Records'][0]['s3']['bucket']['name'] key_path = event['Records'][0]['s3']['object']['key'] response = boto3.resource('s3').Object(bucket_name, key_path).get() # Retrieve the S3 Object # Perform the resize operation with Image(blob=response['Body'].read()) as image: resized_data = resize_image(image, 400, 400).make_blob() # And finally, upload to the resize bucket the new image s3_connection.Object('test-resized', key_path).put(ACL='public-read', Body=resized_data) # Finally remove, as the bucket is public and we don't want just anyone dumping the list of our files! s3_object.delete()배포
코드가 완료되면 새 Lambda 함수로 Amazon Lambda에 업로드해야 합니다. 여기에서 디렉토리 구조에 추가된 Makefile이 작동합니다. 이 Makefile은 생성 중인 Lambda 함수 정의를 배포하는 데 사용됩니다.

ROLE_ARN = arn:aws:iam::601885388019:role/lambda_role FUNCTION_NAME = ResizeImage REGION = us-west-1 TIMEOUT = 15 MEMORY_SIZE = 512 ZIPFILE_NAME = image_resize.zip HANDLER = handler.handle_resize clean_pyc : find . | grep .pyc$ | xargs rm install_deps : pip install -r requirements.txt -t . build : install_deps clean_pyc zip $(ZIPFILE_NAME) -r * create : build aws lambda create-function --region $(REGION) \ --function-name $(FUNCTION_NAME) \ --zip-file fileb://$(ZIPFILE_NAME) \ --role $(ROLE_ARN) \ --handler $(HANDLER) \ --runtime python2.7 \ --timeout $(TIMEOUT) \ --memory-size $(MEMORY_SIZE) update : build aws lambda update-function-code --region $(REGION) \ --function-name $(FUNCTION_NAME) \ --zip-file fileb://$(ZIPFILE_NAME) \ --publish 이 Makefile의 주요 기능은 "만들기"와 "업데이트"입니다. 이러한 함수는 먼저 Lambda 함수를 실행하는 데 필요한 모든 코드를 나타내는 현재 디렉터리를 패키징합니다. 다음으로, requirements.txt 파일에 지정된 모든 종속성은 패키징할 현재 하위 디렉토리에 설치됩니다. 패키징 단계에서는 나중에 "awscli" 명령으로 업로드할 디렉터리의 내용을 압축합니다. Makefile은 다른 Lambda 함수 정의에서 사용하도록 조정할 수 있습니다.
Makefile 유틸리티에서 이미지 생성/업데이트에 필요한 몇 가지 변수를 정의합니다. Makefile 명령이 제대로 작동하려면 필요에 따라 구성하십시오.
-
ROLE_ARN: Lambda 함수를 실행할 역할을 식별하는 Amazon 리소스 이름입니다. -
FUNCTION_NAME: 생성/업데이트 중인 Lambda 함수의 이름입니다. -
REGION: Lambda 함수가 생성/업데이트될 지역입니다. -
TIMEOUT: Lambda 호출이 종료되기 전의 시간 초과(초)입니다. -
MEMORY_SIZE: Lambda 함수가 호출될 때 액세스할 수 있는 메모리 크기(MB)입니다. -
ZIPFILE_NAME: Lambda 함수 코드 및 종속성을 포함하는 압축 패키지의 이름입니다. -
HANDLER: 핸들러 함수의 절대 가져오기 경로(점 표기법).
구성이 완료되면 make create 명령을 실행하면 다음 출력과 유사한 결과가 생성됩니다.
$ make create pip install -r requirements.txt -t . ... find . | grep .pyc| xargs rm zip image_resize.zip -r * ... aws lambda create-function --region ap-northeast-1 \ --function-name ResizeImage2 \ --zip-file fileb://image_resize.zip \ --role arn:aws:iam::11111111111:role/lambda_role \ --handler handler.handle_resize \ --runtime python2.7 \ --timeout 15 \ --memory-size 512 { "CodeSha256": "doB1hsujmZnxZHidnLKP3XG2ifHM3jteLEBvsK1G2nasKSo=", "FunctionName": "ResizeImage", "CodeSize": 155578, "MemorySize": 512, "FunctionArn": "arn:aws:lambda:us-west-1:11111111111:function:ResizeImage", "Version": "$LATEST", "Role": "arn:aws:iam::11111111111:role/lambda_role", "Timeout": 15, "LastModified": "2016-01-10T11:11:11.000+0000", "Handler": "handler.handle_resize", "Runtime": "python2.7", "Description": "" }테스트
생성 명령을 실행한 후 이미지의 크기 조정 기능을 사용할 수 있지만 이벤트를 수신하기 위해 S3 버킷에 연결되지 않았습니다. 함수가 S3 파일 업로드 이벤트를 적절하게 처리하는지 확인하기 위해 AWS 콘솔을 통해 함수를 테스트할 수 있습니다. "서비스" 드롭다운의 "계산" 하위 섹션에서 찾을 수 있는 AWS Lambda 대시보드에서 우리가 생성한 함수의 이름을 선택합니다. 이 Lambda 함수 세부 정보 페이지는 "테스트 이벤트 구성"이라는 옵션이 포함된 "작업"이라는 드롭다운을 제공합니다.
이것을 클릭하면 테스트 이벤트와 몇 가지 예제 템플릿을 지정할 수 있는 모달이 열립니다. "S3 Put" 예를 선택하고 버킷 이름에 대한 언급을 설정한 버킷 이름으로 바꿉니다. 이것이 구성되면 Lambda 함수 페이지에서 "테스트" 버튼을 이후에 사용하면 이전에 구성된 이벤트가 실제로 발생한 것처럼 Lambda 함수가 호출됩니다.
오류 스택 추적 또는 로그 메시지를 모니터링하기 위해 Cloudwatch에서 로그 스트림을 볼 수 있습니다. Lambda 함수가 생성됨과 동시에 새 로그 그룹이 생성됩니다. 이러한 로그 스트림은 유용하며 다른 서비스로 파이프될 수 있습니다.
S3 버킷 이벤트에 연결
S3 대시보드로 돌아가서 "속성" 메뉴에 있는 축소된 "이벤트" 섹션을 확장하여 "이벤트 알림" 양식을 표시합니다. 작성해야 하는 필수 필드는 "이벤트" 및 "보내기" 입력입니다. "이벤트"에서 "객체 생성(전체)" 이벤트를 선택합니다. 이렇게 하면 업로드 버킷에서 객체를 생성하는 모든 이벤트를 가로챌 수 있습니다. "보낸 사람" 입력의 경우 "람다 기능" 라디오 버튼을 선택합니다. 옵션으로 구성한 "ResizeImage" 람다 함수가 포함된 드롭다운이 있는 새 섹션이 나타납니다. "저장"을 클릭하면 "객체 생성" 이벤트가 이제 "ResizeImage" Lambda 함수 호출에 대한 입력으로 라우팅됩니다.
이제 응용 프로그램의 핵심 기능이 있습니다. 모든 것이 예상대로 작동하는지 확인하기 위해 다른 cURL 테스트를 실행해 보겠습니다. cURL을 사용하여 S3 버킷에 이미지를 업로드하고 이미지가 크기 조정 버킷에 업로드되었는지 수동으로 확인합니다.
curl https://test-upload.s3.amazonaws.com -F 'key=test.jpeg' -F '[email protected]'이 명령을 실행하면 Lambda 함수가 이미 "워밍업"되었는지 여부에 따라 50-1000ms 후에 "테스트 크기 조정" 버킷에 크기 조정된 이미지가 생성되어야 합니다.
이미지 나열 Lambda 함수
암호
ListImage Lambda 함수는 크기가 조정된 이미지 목록을 검색하여 사용자의 HTML 페이지에 표시합니다. 이 HTML 페이지는 사용자가 자신의 이미지를 업로드할 수 있는 기능도 제공합니다. Jinja2는 템플릿 정의에서 HTML을 렌더링하는 함수에서 사용됩니다. 이전과 마찬가지로 이러한 요구 사항은 requirements.txt 파일에 지정되어 있습니다.
from __future__ import print_function import os import boto3 from jinja2 import Environment from jinja2 import FileSystemLoader def _render_template(image_urls): env = Environment(loader=FileSystemLoader(os.path.abspath(os.path.dirname(__file__)))) template = env.get_template('list.html') rendered_template = template.render(image_urls=image_urls) return rendered_template def handle_list_image(event, context): bucket = boto3.resource('s3').Bucket('test-resized') image_summaries = sorted((image_summary for image_summary in bucket.objects.all()), key=lambda o: o.last_modified) image_urls = [] for summary in image_summaries: image_urls.append( boto3.client('s3').generate_presigned_url( 'get_object', Params={ 'Bucket': summary.bucket_name, 'Key': summary.key } ) ) return {'htmlContent': _render_template(image_urls)} <html> <head> <title>List Images</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script> var uploadImage = (function () { var inProgress = false; return function () { if (inProgress) { return; } inProgress = true; var formData = new FormData(); var fileData = $('#image-file').prop('files')[0]; formData.append('key', parseInt(Math.random() * 1000000)); formData.append('acl', 'public-read'); formData.append('file', fileData); $.ajax({ url: 'https://test-upload.s3.amazonaws.com/', type: 'POST', data: formData, processData: false, contentType: false, success: function (data) { window.location.reload(); } }); } })(); </script> <style type="text/css"> .image__container { float: left; width: 30%; margin-left: 2.5%; margin-right: 2.5%; max-width: 400px; } </style> </head> <body> <nav> <input type="file" onchange="uploadImage()" value="Upload Image" /> </nav> <section> {% for image_url in image_urls %} <div class="image__container"> <img src="{{ image_url }}" /> </div> {% endfor %} </section> </body> </html>다시 한 번, 이전 Makefile을 변경하고 create 명령을 사용하여 람다 함수를 배포할 수 있습니다.
API 게이트웨이
ImageList Lambda 함수가 완료되었지만 어떤 사용자에게도 제공할 수 없습니다. 이는 Lambda 함수가 다른 서비스의 이벤트에 대한 응답으로 또는 프로그래밍 방식으로만 호출될 수 있기 때문입니다. 여기에서 Amazon AWS API Gateway 서비스가 시작됩니다. API 게이트웨이는 "애플리케이션 서비스" 하위 섹션에서 찾을 수 있습니다.
API 게이트웨이는 끝점을 리소스 및 메서드 집합, 기본적으로 REST 인터페이스로 모델링하는 방법입니다. API Gateway는 요청을 검증하고 변환하는 기능을 제공하는 것 외에도 조절/속도 제한 요청 제공과 같은 다른 기능을 수행합니다.
API Gateway 대시보드에서 ListImage 기능을 제공하기 위한 새 API를 생성합니다. 이름과 설명은 원하는 대로 설정할 수 있습니다. 생성되면 새 API의 이름을 클릭하여 API 세부 정보에 액세스합니다. 루트 URL "/"에 대한 새 리소스를 만듭니다. 이 URL은 HTML 페이지를 제공하는 데 사용됩니다.
루트 리소스 페이지에 대한 세부 정보를 보는 동안 GET 메서드를 추가합니다. "통합 유형"을 "Lambda Function"으로 설정하고 "Lambda Region"을 "us-west-1" 또는 선택한 지역으로 설정하고 ListImage Lambda 함수의 이름을 입력합니다.
HTML 출력에 대한 응답 매핑을 시작하기 전에 이 응답을 콘텐츠 유형에 매핑하는 것 외에도 서버의 응답에 대한 스키마를 정의할 "모델"을 정의해야 합니다. API에 대한 "모델" 섹션을 선택하고 "만들기"를 클릭하여 새 모델을 만듭니다. 컨텐츠 유형이 "text/html"인 모델 이름을 "HTML"로 지정하고 스키마를 다음과 같이 정의합니다.
{ "$schema": "http://json-schema.org/draft-04/schema#", "title" : "HTML", "type" : "object" }API 대시보드로 돌아가서 생성한 리소스를 선택하고 "통합 응답" 섹션으로 이동합니다. 이 섹션에서는 응답을 최종 단계로 연결하기 전에 Lambda 함수에서 응답을 받은 후 처리할 변환을 정의합니다.
"Mapping Templates" 섹션을 열고 "text/html"의 새로운 "Content Type"을 추가합니다. 동시에 이전 "콘텐츠 유형"을 제거하십시오. 오른쪽에서 드롭다운을 "출력 패스스루"에서 "매핑 템플릿"으로 변경합니다. 이렇게 하면 API Gateway에서 허용하는 원시 JSON을 변경하고 반환된 데이터의 "htmlContent" 속성 내 HTML 콘텐츠를 대신 사용할 수 있습니다. 매핑 템플릿의 경우 "$input.htmlContent"를 템플릿으로 지정합니다. 마지막으로 "Response Models for 200"에서 "application/json"을 제거하고 "text/html"을 대신 추가하여 "메소드 응답" 섹션을 변경합니다.
API 대시보드로 돌아가면 페이지 왼쪽 상단에 "API 배포"라는 버튼이 있습니다. 지정된 리소스, 메서드, 모델 및 매핑으로 API를 업데이트하거나 생성하려면 이 버튼을 클릭하십시오. 이 작업이 완료되면 선택한 배포 단계(기본적으로 스테이징)에 대한 URL이 표시됩니다. 드디어 예제가 완성되었습니다! 몇 개의 파일을 업로드하여 크기가 조정된 이미지를 테스트하고 볼 수 있습니다.
마무리
AWS는 대규모 서비스이며 곧 사라지지 않을 것입니다. 공급업체 종속은 항상 주의해야 할 사항이지만 AWS Lambda는 풍부한 보조 구성 옵션 세트와 함께 상대적으로 얇은 서비스를 제공합니다. AWS에서 제공하는 서비스를 활용하여 쉽게 확장 가능하고 유지 관리 가능한 애플리케이션을 구현하면 AWS 플랫폼을 사용할 때 가장 큰 이점을 얻을 수 있습니다. AWS Lambda는 수많은 소비자가 사용하는 엔터프라이즈급 플랫폼을 지원하는 우아하고 확장 가능하며 비용 효율적인 솔루션을 제공합니다. 저는 "서버리스" 애플리케이션이 미래의 길이라고 믿습니다. 아래 의견에 어떻게 생각하는지 알려주십시오.
