코드 예시를 들어주는데 죄다 'Mark'에게 'Hello!'라는 메세지를 보낸다. 같은 예시 뿐이어서, 정말 문자를 보내는 기능인가..? 이런 착각 속에 빠져 있을 즈음,
메세지 대기열이라는 이름을 보고 예약 문자 정도 구나! 단단히 착각에 빠져버렸다.
뭐, 반은 맞고 반은 틀리다.
결제를 시도하는 메세지이므로 순서는 상관 없으나 정확히 1회 처리를 해야 하기 때문에 FIFO를 채택하여 구현하였다.
naming
.fifo로 끝나야 한다.Delay
Delivery delay와 Receive message wait time은 대기열의 모든 메세지에 대한 것으로, 지정한 시간이 지나면 한번에 메세지를 처리한다.Batch size를 1로 조정한다.결국..
SendMessage를 할 때 DelaySeconds를 메세지 마다 각각 보내주는 방식으로 개별 delay를 주는 방법이다.
Promise.all을 사용하여 구현해서 그런가 대기열에 있는 메세지를 검색 → 메세지 보내기 하는 과정에서 대기열에 있는 메세지의 양을 정확히 알 수 없었고, 메세지의 숫자는 0으로 나왔다.index를 증가시켜 10개당 1초의 delay를 줄 수 있게 구현하였다.resources:
Resources:
QueueQueueQueue:
Type: 'AWS::SQS::Queue'
Properties:
ContentBasedDeduplication: true
DelaySeconds: 0
FifoQueue: true
QueueName: "queueName.fifo"
ContentBasedDeduplication : 대기열에 있는 메세지의 내용이 동일하면 해당 메세지는 보내지지 않는다.DelaySeconds : 대기열에 delay를 준다. 개별 메세지에 대한 delay는 아니다.FifoQueue : FIFO 형식을 사용할건지QueueName : Queue이름. FIFO는 뒤에 .fifo를 꼭 붙여야 한다.iamRoleStatements:
- Effect: Allow
Action:
- sqs:SendMessage
- sqs:ReceiveMessage
- sqs:DeleteMessage
- sqs:GetQueueAttributes
Resource:
Fn::GetAtt: [ QueueQueueQueue, Arn ]
Fn::GetAtt: : arn을 직접 쓰지 않고 arn을 가져 올 수 있다.functions:
queue:
handler: queue.queue
name: Backend-Fn-${self:provider.stage}-queue
events:
- sqs:
arn:
Fn::GetAtt:
- QueueQueueQueue
- Arn
batchSize: 1
maximumBatchingWindow: 0
가장 많이 헤맸던 부분이다. 😡
tab을 사용하여 띄어쓰기를 했는데, serverless 개발자 가이드의 예제 코드를 아주 유심히 보면 trigger를 설정 할 때 space 3개 씩 띄어져 있는 것을 볼 수 있다. batchSize : 한번에 메세지를 몇개씩 처리할 지에 대한 설정이다.maximumBatchingWindow : 메세지 수집 시간이다.let sendParams = {
QueueUrl: url,
MessageGroupId: groupName,
MessageBody: JSON.stringify(body)
}
QueueUrl : queue의 url이다. .bash_profile에 저장해놓고 사용하였다.MessageGroupId : FIFO를 사용하기 위해 필수로 필요하다. 대기열 그룹의 아이디이다.MessageBody : 보낼 메세지이다. String 형식만 가능하며, 다른 형식은 message attributes에 넣어 보내주어야 한다.{
"Records": [
{
"messageId": "c451c9e2-00000",
"receiptHandle": "AQEBs1ugEzqRC1yWjeMAvq***",
"body": "{\"key\":2}",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "162704**",
"SequenceNumber": "18863***",
"MessageGroupId": "retry_unpaid",
"SenderId": "AROA5KBD****",
"MessageDeduplicationId": "56a778e****",
"ApproximateFirstReceiveTimestamp": "1627***"
},
"messageAttributes": {},
"md5OfBody": "3b9f0c439***",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:a****.fifo",
"awsRegion": "ap-northeast-2"
}
]
}
event와는 다른 형식이기 때문에, 기존의 handler는 사용할 수 없어서 새로운 handler를 만들어서 사용하였다.receiptHandle, MessageGroupId, body였다.let deleteParams = {
ReceiptHandle: params.receiptHandle,
QueueUrl: params.url
}
receiptHandle를 사용하여 해당 메세지를 지워준다.