sqs.js
var aws = require("aws-sdk");
var config = require("config");
if (config.has("SQS")) {
logger.sys("SQS module loaded.");
}
JavaScript용 AWS SDK
JavaScript용 AWS SDK로 애플리케이션을 개발하고 배포하세요. SDK는 최고의 TypeScript 지원을 제공하며 관용적으로 구성된 TypeScript API를 통해 AWS 서비스를 쉽게 호출하여 Node.js, 웹, 모바일 웹 애플리케이션을 구축합니다.
JavaScript 개발자에게 일관되고 친숙한 JavaScript용 AWS SDK의 라이브러리 세트를 통해 AWS 서비스 사용을 간소화할 수 있습니다. 자격 증명 관리, 재시도, 데이터 순위 결정, 직렬화 및 역직렬화와 같은 API 수명 주기 고려 사항을 지원합니다.
JavaScript용 AWS SDK는 간소화된 개발을 위해 상위 수준의 추상화도 지원합니다. GitHub를 방문하여 AWS 중심 오픈 소스 JavaScript 라이브러리를 확인하세요.
JavaScript용 AWS SDK는 브라우저용 JavaScript, 서버용 Node.js, 모바일 개발용 React Native의 세 가지 런타임을 지원합니다. 또한 교차 런타임을 지원합니다. 서비스 클라이언트 패키지는 코드 변경 없이 브라우저, Node.js 및 React-Native에서 실행할 수 있습니다.
다양한 작업들을 할 때 서로 방해가 되지 않도록 여러 queue사용
ex. 한쪽에서 과부하가 일어났을 때 다른 쪽의 일이 지체되지 않도록
queue + worker가 한 세트로 여러 세트
dev, production 환경 구분 코드
var aws = require("aws-sdk")
var defaultSqs = new aws.SQS(awsConfig);
//awsConfig는 config/development.json파일 안에 있는 객체 복사
if (sqsConfig.everytimeQueue) {
exports.sendMessageToEverytimeQueue = function (message, done) {
var delaySeconds = message.delaySeconds || 0;
//aws에서 제공하고 있는 기능 : sqs의 msg들을 worker에 던지기 전 지연 시간
if (message.data && !message.data.date) {
message.data.date = new Date();
}
if (sqsConfig.everytimeQueue.url) {
//production
defaultSqs.sendMessage({
MessageBody: this.removeInvalidCharacters(JSON.stringify(message)),
QueueUrl: sqsConfig.everytimeQueue.url,
DelaySeconds: delaySeconds
}, done);
} else if (sqsConfig.everytimeQueue.alternativeRequestUrl) {
//development
request.post({
url: sqsConfig.everytimeQueue.alternativeRequestUrl,
json: message
}, function (err) {
if (err) {
logger.sys("SQS Alternative Error: " + err);
}
done(err);
});
} else {
done();
}
};
} else {
exports.sendMessageToEverytimeQueue = function (message, done) {
console.log(JSON.stringify(message));
done();
};
}
notification.js
var removeOldNotification = function (date, done) {
date = new Date(date);
date.setDate(date.getDate() - 61);
date = dateformat(date, "yyyy-mm-dd");
async.eachOfSeries(staticData.campuses, function (campus, campusId, callback) {
sqs.sendMessageToEverytimePushQueue({
//action:string, data:{}을 넘겨준다
//sqs에 던져질 메시지
action: "removeOldNotificationForCampus",
data: {
campusId: campusId,
date: date
}
}, callback);
}, done);
};
cf. JSON.parse(JSON.stringify())
JSON.stringify({ key: undefined });
JSON.stringify({ key: Symbol() });
JSON.stringify({ key: function(){} });
// all will be converted to just "{}"
서버가 sqs에 던진 메시지들을 무한루프를 돌면서 하나씩 받아온다
req.body 안에 message를 받아서 action에 들어간 객체 속 내용을 가지고 일을 하고 괜찮으면 응답코드로 200, 아니면 다른 것들을 보낸다
worker에서 응답은 서버에게 가는 게 아니라 데이터베이스 등 다른 작업들을 해서 영향을 준다
: sqs 자체가 worker와 서버 사이의 dependency를 줄이기 위해 있는 것이기 때문에 직접 소통은 없음
응답 코드가 200이 아니면 visible 속성을 그대로 둔다
worker 레포지토리에서 /everytime-queue로 http api로 서버에서 보낸 메시지를 sqs에서 worker로 전달해주고 있다 (aws에서 제공하는 기능)
응답코드가 200이 아니면 다시 sqs로 들어가서 돌아온다. 이런 과정의 횟수를 aws에서 maxRetries를 통해 정의할 수 있다. 또 응답 시간이 max 몇초가 제한인지 정해놓을 수 있다.(timeout) 이렇게 응답에 실패한 메시지들을 따로 저장하는 dead letter queue를 생성할 수 있다