...
생성된 URL을 입력할 경우, 정상적으로 Redirect 되는지 확인해 봅시다. (본인의 프로젝트에서 생성된 URL을 이용하여 테스트 하세요.)
https://8cqxe1wr4b.execute-api.ap-northeast-1.amazonaws.com/prod/c12778d9
잘 동작하는 것을 볼 수 있습니다.
미션 2. 부하
...
테스트 및 모니터링 대쉬보드 작성
보스는 당신의 실력을 절대적으로 신임합니다. 하지만 성공적인 마케팅을 위해서는 성능을 보장할 수 있는 지표를 알아야 합니다.
이를 증명할 수 있는 부하 테스트 및 모니터링 대쉬보드를 만드는 방법을 살펴 봅니다.
아키텍처 소개
부하 테스트는 Docker 이미지를 만들고 Fargate를 이용해서 Task를 배포하여 테스트 합니다
이 미션은 부하 테스트를 하기 위한 배포 환경을 정의 합니다.
아키텍처 소개
배포 환경 정보를 알 수 있도록 TestEnv라는 스택을 하나 생성하고, 해당 스택을 이용하는 형태로 변경하겠습니다.
draw.io Diagram | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
CDK를 이용한 Custom domain name API 생성
|
트래픽 생성용 Docker 이미지 작성
트래픽 생성용 Docker 이미지를 작성하기 위하여 load-test 폴더를 하나 만듭니다새로운 폴더를 추가합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
mkdir testenvpinger cd testenvpinger |
다음과 같이 ping.sh 파일을 만들고 코드를 넣습니다. 1초 간격으로 URL을 호출합니다해당 폴더에 __init__.py 이라는 파일을 만들고 아래의 코드를 넣습니다. ACCOUNT부터 ZONE_CERT 까지는 본인의 환경에 맞추어 변경하여 만듭니다.
코드 블럭 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
import os
from aws_cdk.core import Stack, Construct, Environment
# we need default values here since aws-cdk-examples build synthesizes the app
ACCOUNT= os.environ.get('TESTENV_ACCOUNT', '123456789012')
REGION = os.environ.get('TESTENV_REGION', 'ap-northeast-1')
VPC_ID = os.environ.get('TESTENV_VPC_ID', 'vpc-0e680e107cb16f0c9')
AWS_ENV = Environment(account=ACCOUNT, region=REGION)
class TestEnvStack(Stack):
"""
A base CDK stack class for all stacks defined in our fun little company.
"""
def __init__(self, scope: Construct, id: str, **kwargs):
super().__init__(scope, id, env=AWS_ENV, **kwargs)
# lookup our pre-created VPC by ID
self._vpc = aws_ec2.Vpc.from_lookup(self, "vpc", vpc_id=VPC_ID)
@property
def testenv_vpc(self) -> aws_ec2.IVpc:
"""
:return: The test env vpc
"""
return self._vpc
__all__ = ["TestEnvStack"] |
* VPC_ID는 Private subnet을 포함하고 있어야 합니다. 만약 없다면, VPC Wizard를 통해서 생성하고 해당 VPC를 연결합니다.
TestEnvStack를 적용
url_short_stack.py 파일을 아래와 같이 수정합니다. 새로운 스택을 가져오고 해당 클래스가 TestEnvStack으로 extends 되는 것을 확인할 수 있습니다. 여기서는 cdk라는 서브 도메인으로 배포를 설정합니다.
코드 블럭 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
from aws_cdk import core, aws_dynamodb, aws_lambda, aws_apigateway
from testenv import TestEnvStack
class UrlShortStack(TestEnvStack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# The code that defines your stack goes here
table = aws_dynamodb.Table(self, "mapping-table",
partition_key = aws_dynamodb.Attribute(name="id",type=aws_dynamodb.AttributeType.STRING))
function = aws_lambda.Function(self, "backend",
runtime=aws_lambda.Runtime.PYTHON_3_7,
handler="handler.main",
code=aws_lambda.Code.asset("./lambda"))
table.grant_read_write_data(function)
function.add_environment("TABLE_NAME", table.table_name)
api = aws_apigateway.LambdaRestApi(self, "api", handler=function) |
Custom domain name으로 API 배포
cdk를 이용해서 배포를 합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cdk deploy |
API Gateway에 해당 도메인으로 배포된 정보를 확인합니다.
Custom domain name 동작 확인
도메인 배포까지 시간이 소요될 수 있습니다. (30분 내외)
https://cdk.awsdemokr.com/715a930b
미션 3. 부하 테스트 및 모니터링 대쉬보드 작성
보스는 당신의 실력을 절대적으로 신임합니다. 하지만 성공적인 마케팅을 위해서는 성능을 보장할 수 있는 지표를 알아야 합니다.
이를 증명할 수 있는 부하 테스트 및 모니터링 대쉬보드를 만드는 방법을 살펴 봅니다.
아키텍처 소개
...
트래픽 생성용 Docker 이미지 작성
트래픽 생성용 Docker 이미지를 작성하기 위하여 load-test 폴더를 하나 만듭니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
mkdir load-test
cd load-test |
다음과 같이 ping.sh 파일을 만들고 코드를 넣습니다. 1초 간격으로 URL을 호출합니다.
코드 블럭 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#!/bin/sh while true; do curl #!/bin/sh while true; do curl -i $URL sleep 1 done |
해당 파일에 대한 실행 권한을 부여합니다.
...
코드 블럭 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
from aws_cdk.core import Construct from aws_cdk import aws_ecs, aws_ec2 # a user-defined construct # just a class the inherits from the core.Construct base class class Traffic(Construct): """ An HTTP traffic generator. Hits a specified URL at some TPS. """ def __init__(self, scope: Construct, id: str, *, vpc: aws_ec2.IVpc, url: str, tps: int): """ Defines an instance of the traffic generator. :param scope: construct scope :param id: construct id :param vpc: the VPC in which to host the traffic generator :param url: the URL to hit :param tps: the number of transactions per second """ super().__init__(scope, id) # define an ECS cluster hosted within the requested VPC cluster = aws_ecs.Cluster(self, 'cluster', vpc=vpc) # define our task definition with a single container # the image is built & published from a local asset directory task_definition = aws_ecs.FargateTaskDefinition(self, 'PingTask') task_definition.add_container('Pinger', image=aws_ecs.ContainerImage.from_asset("pinger"), "pinger"), environment={'URL': url}) # define our fargate service. TPS determines how many instances we # want from our task (each task produces a single TPS) aws_ecs.FargateService(self, 'service', cluster=cluster, cluster=cluster, task_definition=task_definition, desired_count=tps) |
기존 url_short_stack.py 파일을 아래와 같이 수정합니다.
task_definition=task_definition, desired_count=tps) |
기존 url_short_stack.py 파일을 아래와 같이 수정합니다.
코드 블럭 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
from aws_cdk import core, aws_dynamodb, aws_lambda, aws_apigateway, aws_
from traffic import Traffic
import os
# we need default values here since aws-cdk-examples build synthesizes the app
ACCOUNT= os.environ['CDK_DEFAULT_ACCOUNT']
REGION = os.environ['CDK_DEFAULT_REGION']
VPC_ID = os.environ.get('TESTENV_VPC_ID', 'vpc-0e680e107cb16f0c9')
AWS_ENV = Environment(account=ACCOUNT, region=REGION)
class UrlShortStack(core.Stack | ||||||||
코드 블럭 | ||||||||
| ||||||||
from aws_cdk import core, aws_dynamodb, aws_lambda, aws_apigateway from testenv import TestEnvStack from traffic import Traffic class UrlShortStack(TestEnvStack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here table = aws_dynamodb.Table(self, "mapping-table", partition_key = aws_dynamodb.Attribute(name="id",type=aws_dynamodb.AttributeType.STRING)) function = aws_lambda.Function(self, "backend", runtime=aws_lambda.Runtime.PYTHON_3_7, handler="handler.main", code=aws_lambda.Code.asset("./lambda")) table.grant_read_write_data(function) function.add_environment("TABLE_NAME", table.table_name) api = aws_apigateway.LambdaRestApi(self, "api", handler=function) class TrafficStack(TestEnvStack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # lookup Traffic(self, 'TestTraffic',our pre-created VPC by ID vpc_env = aws_ec2.Vpc.from_lookup(self, "vpc", vpc= self.testenv_vpc, url=_id=VPC_ID) # lookup our pre-created VPC by ID test_url = 'https://cdk.awsdemokr.com/715a930b', Traffic(self, 'TestTraffic', vpc= vpc_env, url=test_url, tps=10) |
* VPC_ID는 Private subnet을 포함하고 있어야 합니다. 만약 없다면, VPC Wizard를 통해서 생성하고 해당 VPC를 연결합니다.
app.py 파일을 수정합니다.
코드 블럭 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#!/usr/bin/env python3 from aws_cdk import core from url_short.url_short_stack import UrlShortStack, TrafficStack app = core.App() UrlShortStack(app, "url-short") TrafficStack(app, "test-trafficping") app.synth() |
이제 배포를 합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cdk deploy test-trafficping |
ECS를 들어가면, 현재 동작중인 Fargate Task 숫자 및 상태를 확인할 수 있습니다. 총 10개의태스크가 Fargate로 동작하는 것을 확인할 수 있습니다.
...
Docker 이미지가 ECR에 리포지토리에 저장되어 있는 것을 확인할 수 있습니다.
미션
...
3. 트래픽에 따른 리소스 모니터링
Dynamodb, API Gateway, Lambda가 배포되어 있는 Backend를 모니터링 하기 위해서 CloudWatch 메트릭을 이용할 수 있습니다. 해당 데이터를 모아 보기 위해서는 CloudWatch에서 Dashboard를 만들면 됩니다.
이 작업 역시 CDK를 이용하면 쉽게 구성할 수 있습니다.
아키텍처 소개
draw.io Diagram | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
pypi.org에서 모니터링 관련 cdk를 검색합니다: https://pypi.org/search/?q=aws+cdk+monitoring
...