๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿ’Š Java & Kotlin & Spring/- spring framework +

AWS SDK ๋กœ DLQ ์— ์Œ“์ธ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌํ•˜๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•

by Wonit 2024. 8. 4.

๊ด€๋ จ ๊ธ€

 

์•ž์„  ์‹œ๊ฐ„์— ์šฐ๋ฆฌ๋Š” SQS ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Spring Boot 3 ๋กœ producer/consumer ๋ฅผ ๊ตฌํ˜„ ํ•˜์—ฌ DLQ ๋ฅผ ์ด์šฉํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌ ํ•˜์˜€๋‹ค.

 

DLQ ์— ์Œ“์ธ ๋ฉ”์‹œ์ง€๋“ค์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•˜๋‹ค. ์ง์ ‘ console ์„ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ  programmatically ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” web console UI ๊ฐ€ ์•„๋‹Œ programmatically ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ์˜ˆ์ •์ด๋‹ค.

 

๋ชฉ์ฐจ

  1. ๋ฐฐ๊ฒฝ
  2. DLQ ์™€ redrive
  3. DLQ ์— ์Œ“์ธ message redrive ํ•˜๊ธฐ
  4. ํŠน์ • message ๋งŒ redrive ํ•˜๊ธฐ

๋ฐฐ๊ฒฝ

ํšŒ์‚ฌ์—์„œ ํŠน์ • ์‹œ์Šคํ…œ์—์„œ SQS ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, DLQ ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ์ฒ˜๋ฆฌ์— ์‚ดํŒจํ•œ ๋ฉ”์‹œ์ง€๋“ค์„ ๊ด€๋ฆฌํ•œ๋‹ค.

 

๋ณดํ†ต consumer ์—์„œ message ์ฒ˜๋ฆฌ์— ์‹คํŒจํ•˜๋Š” ์ด์œ ๋Š” 2๊ฐ€์ง€๋กœ ๋‚˜๋‰œ๋‹ค.

 

  1. ์ผ์‹œ์ ์ธ ์—๋Ÿฌ
  2. ๋ณด์ •์ด ํ•„์š”ํ•œ ์—๋Ÿฌ

๋ณดํ†ต 1๋ฒˆ์€ network timeout ์ด๋‚˜ service temporary unavailable ๊ณผ ๊ฐ™์€ ์ผ€์ด์Šค๋กœ ๋Œ€๋ถ€๋ถ„ ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„์— retry ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

ํ•˜์ง€๋งŒ 2๋ฒˆ์˜ ๊ฒฝ์šฐ๋Š” ๊ฐœ๋ฐœ์ž๋‚˜ ์šด์˜์ž๊ฐ€ ์ˆ˜๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๊ณ  ๋ณด์ •์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

 

๋ณด์ •์ด ์™„๋ฃŒ๋˜๋ฉด message ๋ฅผ redrive ํ•˜์—ฌ ์žฌ์‹œ๋„๋ฅผ ํ•œ๋‹ค.

 

ํ•˜์ง€๋งŒ ์‚ฌ๋‚ด์˜ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ •์ฑ…์— ์˜ํ•ด aws console ์— ์ ‘๊ทผํ•˜๊ธฐ๊ฐ€ ๊ท€์ฐฎ๊ณ  ๋ณต์žกํ•˜๊ธฐ์— ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๊ฐ€ ์‹ฌํ–ˆ๊ณ  ์ด๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ๊ณ  ์ด๋ฅผ Spring Boot 3.x ์™€ kotlin ์œผ๋กœ ๊ตฌํ˜„ํ•œ ๋‚ด์šฉ๋“ค์„ ๊ณต์œ ํ•ด๋ณด๋ ค ํ•œ๋‹ค.

 

DLQ ์™€ redrive

SQS ๋ฅผ ํ†ตํ•ด messaging infrastructure ๋ฅผ ๊ตฌ์„ฑํ•œ application ์—์„œ๋Š” DLQ ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ์‹คํŒจ์— ๋Œ€ํ•ด ๋Œ€์‘ํ•œ๋‹ค.

 

2014๋…„ AWS ๊ฐ€ ์ฒ˜์Œ์œผ๋กœ DLQ ๋ฅผ ์ถœ์‹œํ•˜๊ธฐ ์ „์€ consumer application ์—์„œ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ์— ์‹คํŒจํ•˜๋ฉด ํ•ด๋‹น ๋ฉ”์‹œ์ง€๊ฐ€ retention ๊ธฐ๊ฐ„๋™์•ˆ ๊ณ„์†ํ•ด์„œ queue ์— ๋‚จ์•„ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

๊ฒฐ๊ตญ consumer application ์€ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•˜๋Š” message ๋ฅผ ๊ณ„์†ํ•ด์„œ ์Œ“์•„๋†“์Œ์œผ๋กœ์จ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๋‚ฎ์„ ์ˆ˜ ๋ฐ–์— ์—†์—ˆ์ง€๋งŒ.

AWS ๋Š” 2014๋…„ DLQ ๋ฅผ ๊ณต๊ฐœํ•˜๋ฉฐ SQS ์—์„œ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ณ„์†ํ•ด์„œ queue ์— ๋‚จ์•„์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€๋‹ค.

 

 

DLQ ์— ๋Œ€ํ•œ ์„ค์ •๊ณผ ๊ตฌ์„ฑ์€ ์ง€๋‚œ ์‹œ๊ฐ„์— ์‹ค์Šต์„ ํ†ตํ•ด ์•Œ์•„๋ณธ DLQ ๋กœ SQS Consumer ์—๋Ÿฌ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

message redrive ๋ž€?

 

redrive ๋ž€, DLQ ์— ์ €์žฅ๋œ ๋ฉ”์‹œ์ง€๋ฅผ consumer application ์ด ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค์‹œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก origin queue ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

 

2021๋…„ AWS re:Invent ์—์„œ ์ฒ˜์Œ์œผ๋กœ DLQ ๋ฅผ aws web console UI ์—์„œ redrive ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์˜€๋‹ค.

 

 

ํ•˜์ง€๋งŒ ์ด๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ปจํŠธ๋กค ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์—ˆ๊ณ  ํœด๋จผ ์—๋Ÿฌ๊ฐ€ ๊ฐ€๋“ํ•œ ๊ฐœ๋ฐœ์ž๋“ค์˜ ์ˆ˜๋™์˜ ์˜์—ญ์œผ๋กœ ๋‚จ์•„์žˆ์—ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ 2023๋…„ 6์›” 8์ผ Aws ์—์„œ๋Š” DLQ ๋ฅผ handling ํ•˜๋Š” ์ƒˆ๋กœ์šด API ๋ฅผ ๊ฐœ๋ฐœํ•˜์—ฌ AWS Sdk ์— ํฌํ•จ์‹œ์ผฐ๋‹ค.

 

DLQ ์— ์Œ“์ธ ๋ฉ”์‹œ์ง€ redrive ํ•˜๊ธฐ

 

AWS consule UI ๊ฐ€ ์•„๋‹Œ cli ๋‚˜ sdk ๋กœ DLQ ์— ์Œ“์ธ ๋ฉ”์‹œ์ง€๋ฅผ redrive ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” start-message-move-task ๋ผ๋Š” ์ปค๋งจ๋“œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์•„๋ž˜์˜ ์ œ์•ฝ์กฐ๊ฑด์—๋งŒ ํ•ด๋‹น๋œ๋‹ค๋ฉด DLQ ์—์„œ origin queue ๋กœ message ๋ฅผ redrive ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

  • DLQ ๊ตฌ์„ฑ์ด ๋œ queue ๋กœ๋งŒ redrive ํ•  ์ˆ˜ ์žˆ์Œ
  • DLQ ์˜ ์ „์ฒด message ๊ฐ€ redrive ๋จ์„ ๊ณ ๋ คํ–์•  ํ•จ

๊ตฌํ˜„ํ•˜๊ธฐ

 

์šฐ์„  AWS SDK ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ ๋‚˜๋Š” Spring Boot ๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ๊ณ  Spring Cloud AWS ์—์„œ ์ œ๊ณตํ•˜๋Š” io.awspring.cloud:spring-cloud-aws-starter-sqs:3.1.1 ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ๊ฒƒ์ด๋‹ค.

์‹ค์Šต์— ์‚ฌ์šฉ๋œ ๋ชจ๋“  ์†Œ์Šค์ฝ”๋“œ๋Š” https://github.com/my-research/try-aws-sdk ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์•„๋ž˜ Controller ๋Š” API ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด DLQ ๋ฅผ ์›๋ณธ ํ๋กœ ๋‹ค์‹œ redrive ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

@RestController
class SupportSqsController(
  private val sqsClient: SqsAsyncClient,
) {
  @GetMapping("/re-drive/messages")
  fun reDriveAll() {
    val request = StartMessageMoveTaskRequest.builder()
      .sourceArn(MEMBER_DLQ_ARN)
      .destinationArn(MEMBER_QUEUE_ARN)
      .build()

    sqsClient.startMessageMoveTask(request)
  }
}

startMessageMoveTask ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” spring-cloud-aws-starter-sqs ์—์„œ sqs client ๋กœ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋Š” SqsTemplate ์ด ์•„๋‹Œ SqsAsyncClient ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

SqsAsyncClient ๋ฅผ ํ†ตํ•ด startMessageMoveTask ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ์ธ์ž๋กœ source ์™€ destination ๋งŒ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

ํ…Œ์ŠคํŠธํ•˜๊ธฐ (๊ฒ€์ฆ)

์‹ค์Šต์—์„œ ์‚ฌ์šฉ๋œ SQS ์™€ consumer / config ์ •๋ณด๋“ค์€ ์•ž์„  ์‹ค์Šต ๊ธ€์ธ AWS SQS + Spring Boot 3 + kotlin ์ธํ”„๋ผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์™€ AWS SQS Consumer ์—๋Ÿฌ๋ฅผ DLQ ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ „์ฒด ์†Œ์Šค์ฝ”๋“œ๋Š” github ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

GitHub - my-research/try-aws-sdk: aws sdk for java spring

aws sdk for java spring. Contribute to my-research/try-aws-sdk development by creating an account on GitHub.

github.com

 

 

์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด์„œ DLQ ์— ๋‹ค์Œ 2 ๊ฐœ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์Œ“์•˜๋‹ค.

 

 

redrive policy ์— ์˜ํ•ด 3ํšŒ retry ํ›„ ์ตœ์ข…์ ์œผ๋กœ ack ๊ฐ€ ๋˜์ง€ ์•Š์•„ DLQ ์— 2๊ฐœ์˜ ๋ฉ”์‹œ์ง€๊ฐ€ ์Œ“์ธ ์ƒํƒœ์ด๋‹ค.

 

 

๊ทธ๋ฆฌ๊ณ  ์•ž์„œ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  API ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ „์ฒด์˜ message ๊ฐ€ redrive ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๋ฌธ์ œ์ 

 

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ–ˆ์„ ๋•Œ ์น˜๋ช…์ ์ธ ๋ฌธ์ œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.

 

์ „์ฒด ๋ฉ”์‹œ์ง€๋ฅผ redrive ํ•˜๊ธฐ๋Š” ์ข‹๊ฒ ์ง€๋งŒ ์›์น˜ ์•Š๋Š” message ๋“ค ๊นŒ์ง€ redrive ๋˜์–ด ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•˜๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

(ํ˜„์žฌ ๋ฒ„์ „์—์„œ๋Š” ๊ฐœ๋ณ„ message ๋งŒ redrive ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋“ฏ ํ•˜๋‹ค..)

 

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” DLQ ์—์„œ messageId ๋กœ ๊ฐœ๋ณ„ ๋ฉ”์‹œ์ง€๋“ค์„ ์‹๋ณ„ํ•˜๊ณ  ์›๋ณธ ํ๋กœ ๋ณด๋‚ด ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋ฅผ DLQ ์—์„œ ์ˆ˜๋™์œผ๋กœ ์ œ๊ฑฐํ•ด์ค˜์•ผ ํ•œ๋‹ค.

 

์•„๋ž˜์—์„œ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๋„๋กํ•˜์ž

 

ํŠน์ • message ๋งŒ redrive ํ•˜๊ธฐ

 

์ด ๋ฐฉ๋ฒ•์€ 2023๋…„์— ์‹ ๊ทœ๋กœ ์ถœ์‹œ๋œ ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ ๊ธฐ์กด์— ์กด์žฌํ•˜๋˜ Aws SDK ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

์ปจ์…‰์€ ๊ฐ„๋‹จํ•˜๋‹ค.

  1. DLQ ์—์„œ message ๋ฅผ polling
  2. ํŠน์ • messageId ๋กœ message ๋ฅผ filter
  3. ํ•ด๋‹น message ๋ฅผ ์›๋ณธ ํ๋กœ ๋‹ค์‹œ ์ „์†ก
  4. ํ•ด๋‹น message ๋ฅผ DLQ ์—์„œ ์ œ๊ฑฐ

๊ตฌํ˜„ํ•˜๊ธฐ

 

์•„๋ž˜๋Š” ๊ฐ„๋‹จํ•œ Controller ์ด๋‹ค.

 

/messages/{id} ๋ฅผ ํ†ตํ•ด messageId ๋ฅผ ์ „๋‹ฌ ๋ฐ›๊ณ  ํ•ด๋‹น id ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฐพ์•„ ์›๋ณธ ํ๋กœ ์ „์†กํ•˜์—ฌ DLQ ์—์„œ ์ œ๊ฑฐํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

@RestController
class SupportSqsController(
  private val sqsClient: SqsAsyncClient,
) {
  @GetMapping("/re-drive/messages/{id}")
  fun reDriveBy(@PathVariable id: String) {
    val messages = receiveMessages()
    // ๋””๋ฒ„๊น… ๋กœ๊ทธ ์ถ”๊ฐ€
    if (messages.isEmpty()) {
      return@repeat
    }
    val reDriveTarget = messages.firstOrNull { it.messageId() == id }
    reDriveTarget?.let {
      reDriveMessage(id, it)
      deleteMessage(it, id)
      return
    }
  }

  /**
   * message ๋ฅผ polling
   */
  private fun receiveMessages(): MutableList<Message> {
    val request = ReceiveMessageRequest.builder()
      .queueUrl(MEMBER_DLQ_NAME)
      .maxNumberOfMessages(2)
      .waitTimeSeconds(10)
      .maxNumberOfMessages(10)
      .visibilityTimeout(3)
      .build()
    val messageFuture = sqsClient.receiveMessage(request)

    val messages = messageFuture.get().messages()
    println("Received messages: ${messages.size}")
    return messages
  }
  /**
   * message ๋ฅผ ๋‹ค์‹œ origin ํ๋กœ send
   */
  private fun reDriveMessage(id: String, it: Message) {
    println("$id ์— ํ•ด๋‹นํ•˜๋Š” message ์กด์žฌํ•˜์—ฌ origin queue ๋กœ redrive")
    sqsClient.sendMessage(SendMessageRequest.builder()
      .queueUrl(MEMBER_QUEUE_NAME)
      .messageBody(it.body())
      .build())
  }

  /**
   * DLQ ์—์„œ message ๋ฅผ ์ œ๊ฑฐ
   */
  private fun deleteMessage(it: Message, id: String) {
    val deleteMessageRequest = DeleteMessageRequest
      .builder()
      .queueUrl(MEMBER_DLQ_NAME)
      .receiptHandle(it.receiptHandle())
      .build()
    sqsClient.deleteMessage(deleteMessageRequest)
    println("DLQ ์—์„œ message($id, ${it.receiptHandle()}) ์ œ๊ฑฐ๋จ")
  }
}

 

์ด์ œ ์‹ค์Šต์„ ํ†ตํ•ด ํ™•์ธํ•ด๋ณด์ž.

 

ํ…Œ์ŠคํŠธํ•˜๊ธฐ (๊ฒ€์ฆ)

 

์•ž์„  ํ…Œ์ŠคํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด์„œ DLQ ์— ๋‹ค์Œ 2 ๊ฐœ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์Œ“์•˜๋‹ค.

 

 

์ฐธ๊ณ ๋กœ messageId ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” console ์—์„œ ์ง์ ‘ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด consumer ์—์„œ messageHeader ๋ฅผ parsing ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

@SqsListener("member-event")
  fun listen(
    @Header(value = "id") messageId: String,
    message: String
  ) {
    println("received message(id:$messageId,$message)")
  }

 

๊ทธ๋ฆฌ๊ณ  ์•ž์„œ ๋งŒ๋“  API ๋ฅผ ํ†ตํ•ด ๊ฐœ๋ณ„ redrive ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ ์›๋ณธ Q ๋กœ ๋ฉ”์‹œ์ง€๊ฐ€ redrive ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

redrive ๊ฐ€ ๋˜์–ด ๋‹ค์‹œ ์›๋ณธ ํ์˜ redrive policy ํšŸ์ˆ˜๋งŒํผ retry ๋ฅผ ์ˆ˜ํ–‰ํ•˜์˜€๋‹ค.

 

์•ž์„  ๊ตฌํ˜„์—์„œ๋Š” 2๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด ์กด์žฌํ•œ๋‹ค.

 

  1. polling ์ด ์•„๋‹˜
  2. message ๋ฅผ redrive ํ•˜๋ฉด ์‹ ๊ทœ message ๊ฐ€ ์ƒ์„ฑ๋จ

 

์•ž์„  ํ•จ์ˆ˜ receiveMessages() ๋Š” polling ์ด ์•„๋‹ˆ๋‹ค. maxNumberOfMessages ๋งŒํผ ๋‹จ์ง€ receive ํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

๋งŒ์•ฝ ๋ฉ”์‹œ์ง€๊ฐ€ 1000๊ฐœ ์Œ“์—ฌ์žˆ๋‹ค๋ฉด maxNumberOfMessage ์†์„ฑ ์ˆ˜์˜ ์ตœ๋Œ€์ธ 10๋งŒํผ๋งŒ ํ•œ ๋ฒˆ ์ˆ˜์‹ ํ•˜๊ณ  ๋๋‚œ๋‹ค.

 

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” repeat(n) ๊ณผ ๊ฐ™์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ receiver ๋ฅผ polling ํ˜•์‹์œผ๋กœ ๊ตฌํ˜„ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

 

๋˜ํ•œ redrive ํ•œ๋‹ค๋ฉด message ๋ฅผ ์›๋ณธ ํ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‹ ๊ทœ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฐœํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

๊ทธ๋ž˜์„œ messageId ๊ฐ€ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์œ ์˜ํ•ด์•ผ ํ•œ๋‹ค.

 

Refs

๋Œ“๊ธ€