AWS 클라우드 환경을 기반으로 하는 느슨하게 연결된 (loosely coupled) 어플리케이션 아키텍처에 대한 이해
메시지 큐의 Pub/Sub 패턴과 Producer/Consumer 패턴의 차이를 이해한다
DB와 서버와의 통신이 가능하도록 연결한다
특정 상황에서 SNS, SQS로 메세지가 전달되도록 시스템을 구성한다
SQS에 들어온 메세지를 레거시 시스템(Factory API)으로 전달하는 시스템을 구성한다
레거시 시스템(Factory API)의 콜백 대상이되는 리소스를 생성해 데이터베이스에 접근 할 수 있게 한다
( 구성되어있는 데이터 베이스에 접근하여 개인별 데이터 베이스 리소스에 table을 생성하고 값 추가)
// MacOS mysql 설치% brew install mysql
// mysql 설치 유무 확인% mysql -V
- mysql 접속 (로그인)
mysql -h <RDS 데이터 베이스 경로> -u <username입력> -p <password입력>
// -p 는 password 를 사용한다는 뜻
- database 목록 확인
mysql> show databases;
mysql> use <데이터 베이스 명>
mysql> show tables;
=> BIN_TO_UUID(factory_id), BIN_TO_UUID(ad_id) 값 확인하여 수정
-- RDS에 생성한 데이터베이스 리소스에 아래 table들을 생성하고, 값을 추가해넣으세요.
CREATE TABLE `product` (
`product_id` BINARY(16) NOT NULL ,
-- http://mdr.tta.or.kr/item/1036/property/sku`sku` varchar(200) NOT NULL ,
-- Field documentation comment 3
`name` varchar(200) NOT NULL ,
`price` int NOT NULL ,
`stock` int NOT NULL ,
`factory_id` BINARY(16) NOT NULL ,
`ad_id` BINARY(16) NOT NULL ,
PRIMARY KEY (
`product_id`
),
CONSTRAINT `uc_product_sku` UNIQUE (
`sku`
),
CONSTRAINT `uc_product_name` UNIQUE (
`name`
)
);
CREATE TABLE `factory` (
`factory_id` BINARY(16) NOT NULL ,
-- http://mdr.tta.or.kr/item/1036/property/sku`identifier` varchar(200) NOT NULL ,
-- Field documentation comment 3
`name` varchar(200) NOT NULL ,
`manager_email` varchar(200) NOT NULL ,
`API` varchar(200) NOT NULL ,
PRIMARY KEY (
`factory_id`
),
CONSTRAINT `uc_factory_name` UNIQUE (
`name`
)
);
CREATE TABLE `advertisement` (
`ad_id` BINARY(16) NOT NULL ,
`status` boolean NOT NULL ,
`manager_email` varchar(200) NOT NULL ,
PRIMARY KEY (
`ad_id`
)
);
ALTER TABLE `product` ADD CONSTRAINT `fk_product_factory_id` FOREIGN KEY(`factory_id`)
REFERENCES `factory` (`factory_id`);
ALTER TABLE `product` ADD CONSTRAINT `fk_product_ad_id` FOREIGN KEY(`ad_id`)
REFERENCES `advertisement` (`ad_id`);
INSERT INTO factory(factory_id, identifier, name, manager_email, api) VALUES(UUID_TO_BIN(UUID()),'FF-500293','부산도너츠 공장', 'dob_factory@codeatates.com', '');
INSERT INTO advertisement(ad_id, status, manager_email) VALUES(UUID_TO_BIN(UUID()),true, 'dob_ad@codeatates.com');
SELECT
BIN_TO_UUID(factory_id) as factory_id
FROM factory;
-- <출력값 1>
SELECT
BIN_TO_UUID(ad_id) as ad_id
FROM advertisement;
-- <출력값 2>
INSERT INTO product(product_id, sku, name, price, stock, factory_id, ad_id)
VALUES(UUID_TO_BIN(UUID()),'CP-502101','부산도너츠', 19900, 3, UUID_TO_BIN("<출력값 1>"),
UUID_TO_BIN('<출력값 2>'));
mysql> select * from product;//만약 물품 구매 테스트 후 stock이 0 이 된다면 // mysql> UPDATE product SET stock = 3;
HOSTNAME=<RDS 데이터 베이스 입력>
USERNAME=<id 입력>
PASSWORD=<password 입력>
DATABASE=<깃허브 유저아이디>
% npm install% npm start
- curl 명령어를 통하여 GET, POST 메소드 실행 및 결과 확인
- $ curl -X GET localhost:8080/product/donut응답 : {"product_id":"","name":"부산도너츠", "price":19900,"stock":3,"BIN_TO_UUID(factory_id)":"","BIN_TO_UUID(ad_id)":"~~"}
- $ curl -X POST localhost:8080/checkout첫번째 응답 : {"message":"구매 완료! 남은 재고: 2"}두번째 응답 : {"message":"구매 완료! 남은 재고: 1"}세번째 응답 : {"message":"구매 완료! 남은 재고: 0"}네번째 응답 : {"message":"구매 실패! 남은 재고: 0"}오류{"message":"데이터베이스 연결 오류"} 라는 오류가 뜸 - .env를 상위 디렉토리에 저장하여 생긴 오류
% sls deploy // 배포하기 // 람다 함수 생성 확인
SNS 구독
const now = new Date().toString()
const message = `도너츠 재고가 없습니다. 제품을 생산해주세요! \n메시지 작성 시각: ${now}`
const params = {
Message: message,
Subject: '도너츠 재고 부족',
MessageAttributes: {
MessageAttributeProductId: {
StringValue: product.product_id,
DataType: "String",
},
MessageAttributeFactoryId: {
StringValue: req.body.MessageAttributeFactoryId,
DataType: "String",
},
},
TopicArn: process.env.TOPIC_ARN
}
const result = await sns.publish(params).promise()
TOPIC_ARN=<SNS 엔드포인트>
% curl --location --request POST 'https://API_GATE_ID.execute-api.ap-northeast-2.amazonaws.com/checkout' --header 'Content-Type: application/json' --data-raw '{ "MessageGroupId": "stock-empty-group", "subject": "부산도너츠 재고 부족", "message": "재고 부족", "MessageAttributeProductId": "CP-502101", "MessageAttributeFactoryId": "FF-500293"}'
오류
{"message":"Internal Server Error"} 응답이 오고 AWS 콘솔 내 테스트에서 handler or export 문제가 있다는 오류가 출력될 경우
소스 코드 내 아래 소스 작성 되어 있는지 확인 => 테스트 하다가 지워버렸었음
module.exports.handler = serverless(app);
module.exports.app = app;
- SQS 사용 가능한 메시지 증가
% serverless
// starter 템플릿 생성// 배포 확인 시 n 으로 진행
- .yml 파일 수정 -> 리전 추가
provider:
name: aws
runtime: nodejs18.x
region: ap-northeast-2
function delay(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
exports.handler = async (event) => {
await delay(50000)
console.log(event)
return event
}