2025. 2. 2. 16:47γBackend
μ΅κ·Ό νμ¬μμ μ§ν μ€μΈ μμ μμ μλμ κ°μ μꡬμ¬νμ λ§λκ² λμμ΅λλ€.
- μλΉμ€ λ΄μλ μ λ§μ ν λνΈκ° μ‘΄μ¬
- κ° ν λνΈ λ΄μμλ νΉμ μ΄λ²€νΈκ° λ°μνκ³ , μ΄λ₯Ό μ²λ¦¬νλ μ컀 λ‘μ§μ΄ νμ (νλ² μ€νμ 500ms ~ 5s, ν λνΈ λ΄ λ°μ΄ν° μμ λΉλ‘)
- μ΄λ²€νΈ λ°μ λΉλλ λμ§ μμ
- μ΄ λ μ΄λ€ μ컀 λ‘μ§μ ν λνΈ λ³λ‘ μ€λ‘μ§ νλμ©λ§ λμν΄μΌ ν¨. (ν λνΈ λ΄ λμμ± X)
ν΄λΉ κΈμμλ μ΄ μꡬμ¬νμ λ§μ‘±μν€κΈ° μν λ°©μμ λν΄ λ€λ€λ³΄λλ‘ νκ² μ΅λλ€.
μ΅μ΄ ꡬν
μ΄κΈ°μλ μ΄ μꡬμ¬νμ λ§μ‘±μν€κΈ° μν΄, μλμ κ°μ λ°©ν₯μ±μΌλ‘ μμ μ μ§ννμ΅λλ€. κ° κ΅¬μ‘°μ λν μ€λͺ μ μλμ κ°μ΅λλ€.
- μλ² μ ν리μΌμ΄μ μμλ μ μ μ νΉμ νλμ λ°λΌ μ΄λ²€νΈλ₯Ό λ°ννμ¬ SQSλ‘ μ λ¬ν©λλ€.
- μ λ¬λ μ΄λ²€νΈλ μ¬μ μ λ±λ‘λ AWS λλ€λ₯Ό νΈλ¦¬κ±°νμ¬ μλΉλ©λλ€.
- μ΄ λ λλ€μμλ μμ μ μμ, ν λνΈ λ³ μ μΌμ±μ 보μ₯νκΈ° μν΄ ν λνΈ μλ³μλ₯Ό ν΅ν λΆμ°λ½μ μμ²ν©λλ€. μ΄ λ λΆμ°λ½μ Mysqlμ Named Lockμ ν΅ν΄ ꡬννμμ΅λλ€.
- Named Lockμ λκΈ°νλ€κ° μ΅λ λκΈ° μκ°(10s)μ λμ΄κ°λ μΌμ΄μ€λ DLQλ₯Ό ν΅ν΄ νμ λ€μ λ£μ΄μ£Όλλ‘ κ΅¬ννμ΅λλ€.
μ΅μ΄ ꡬν λ°©μμ λ¬Έμ
μμ²λΌ ꡬννκ³ λλ ν¬κ² λκ°μ§ λ¬Έμ κ° μμμ΅λλ€.
첫λ²μ§Έλ λΉμ© λ¬Έμ μ λλ€.
μ ꡬ쑰μμλ μ΄λ²€νΈκ° νμ λ€μ΄κ°κ³ λλ©΄ μΌλ¨ λλ€λ₯Ό λμ°κ³ κ±°κΈ°μμ λΆμ°λ½μ λκΈ°νλ©° ν λνΈ λ³ λμμ±μ μ μ΄ν©λλ€. λλ€μ κ²½μ°μ μ€μ μ€νμκ°μ λΉλ‘νμ¬ λΉμ©μ΄ λ°μνκΈ° λλ¬Έμ, μ€μ λ‘μ§μ λμ μΈμ λΆνμνκ² λ½μ λκΈ°νλ μκ°μ΄ λͺ¨λ λΉμ©μ ν¬ν¨λκ² λ©λλ€. μ΄λ²€νΈκ° μ€νμ±μΌλ‘ λ§μ΄ λ°μνλ μν©μμλ λ¨ 10μ΄ κ° μ€νλ μ μλ λ§νΌμ μ΄λ²€νΈλ§ μλΉλκ³ , λλ¨Έμ§ μ΄λ²€νΈλ€μ μ λΆ 10μ΄ κ° λκΈ° ν μ¬μλνκ² λλλ° λμμ± μ μ΄λ₯Ό μν λ½ λκΈ°μ κ±°μ λͺ¨λ μκ°μ΄ μλΉλμ΄ λΉμ©μ μΈ μΈ‘λ©΄μμ μμ²λ λλΉκ° λ°μν©λλ€.
λλ²μ§Έλ νΌμ‘ μ μ΄ λ¬Έμ μ λλ€.
μ ꡬ쑰μμλ λμμ λ°μν μ΄λ²€νΈλ€ μ€, λ½μ νλν λ¨ νλμ νλ‘μΈμ€λ₯Ό μ μΈνλ©΄ μ¬μλ λ¨κ³μμ κ·Έλλ‘ λμΌν κ²½μμλ€κ³Ό κ²½ν©μ΄ λ°μν©λλ€. μ΄λ μμμ μΈκΈν λΉμ© λ¬Έμ λ₯Ό λμ± μ¬νμν΅λλ€.
νλ² κ°μ λ ꡬν λ°©μ
λ€μμ μ΅μ΄ ꡬνμμ λ°μνλ λ¬Έμ λ₯Ό ν΄μν ꡬ쑰μ λλ€. μ μ©λ μμ΄λμ΄λ μλμ κ°μ΅λλ€.
- κ° μ΄λ²€νΈλ€μ μ΄λ²€νΈ νμ΄λ‘λ λ΄μ μ΅λ μ¬μλ νμλ₯Ό κ°μ΅λλ€.
- μ΄λ²€νΈλ‘ μΈν΄ νΈλ¦¬κ±°λ λλ€ μ컀μμ λΆμ°λ½ νλμ μλλ νλ, λκΈ°λ νμ§ μμ΅λλ€.
- λΆμ°λ½ νλμ μ€ν¨ν μ΄λ²€νΈλ€μ νμ΄λ‘λ λ΄ μ¬μλ νμλ₯Ό νλ κ°μμν¨μ± νμ λ€μ λ°μ΄λ£μ΅λλ€.
- μ΄ λ SQS Delay Seconds μ΅μ μ λμ νμ¬ λΆμ°λ½ νλ νλ‘μΈμ€μ λ‘μ§μ΄ λλ λ€ λλ€μ μ λ¬λ μ μλλ‘ ν μ κ°μ§λλ€.
- μ¬μλ νμκ° λμ΄λ μλ‘ νμ¬ ν΄λΉ ν λνΈμ λν μ΄λ²€νΈκ° μ λ°μ μΌλ‘ νΌμ‘ν κ²μ΄κΈ° λλ¬Έμ, μ¬μλ νμκ° λμ΄λ μλ‘ λκΈ° μκ°μ΄ μ§μμ μΌλ‘ μ¦κ°νλ ExponentialBackoffλ₯Ό λμ νμ¬ Delay Secondsλ₯Ό κ³μ°ν©λλ€.
- λͺ¨λ μ€ν¨ μ΄λ²€νΈλ€μ΄ λμΌν Delay Secondsλ₯Ό κ°μ§ κ²½μ° λ€μ νμ΄μ¦μμ λμΌνκ² κ²½μν κ²μ΄κΈ° λλ¬Έμ, Backoff μκ°μ κ³μ°ν λ λλ€μ±μ μΆκ°ν©λλ€.
- μ΄μ λ°©μμ λΉν΄ νκ· μ¬μλ νμκ° λμ΄λ κ²μ΄κΈ° λλ¬Έμ μ΅λ μ¬μλ νμλ₯Ό λλνκ² μ£Όλλ‘ νκ³ , μ΅λ μ¬μλ νμλ₯Ό λμ κ²½μ°μ DLQλ₯Ό ν΅ν΄ κ°λ°μλ€μ΄ μ μ μκ² ν©λλ€.
μμ μ κ·Όμ λ¬λ¦¬νμ¬ (with SQS FIFO Queue)
μμ κ°μ΄ κ°μ μ μ§ννμ§λ§, μ¬μ ν νκ³λ μ‘΄μ¬νμ΅λλ€.
무μλ³΄λ€ λ½μ λκΈ° μκ°μ μ΅μννκΈ΄ νμΌλ μ΄μ¨λ λλ€ μ컀λ μ€νλλ κ²μ κ³μ κ±°μ¬λ¦¬λ μ§μ μ΄μμ΅λλ€.
λλ€ λ 벨μμλ μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ€κ³ νλ¨νκ³ , SQS μͺ½ λ¬Έμλ₯Ό λ νμΈν΄λ΄€λλ° κ²°λ‘ μ μΌλ‘λ SQS FIFO Queueλ₯Ό μ΄λ―Έ μ§μμ νκ³ μμκ³ μ΄λ₯Ό μ¬μ©νλ©΄ λλ λ¬Έμ μμ΅λλ€.
λ€λ§ FIFO QueueλΌκ³ ν΄μ μμ λμμ±μ΄ 1λ‘ μ νλλ κ²μ΄λΌλ©΄ λμ μ΄ μ΄λ €μ μν λ°, SQSμμλ FIFO Queue λ΄λΆμ μΌλ‘ Message Groupμ κ΄λ¦¬νκ³ κ°μ κ·Έλ£Ήμ λ©μμ§λ€μ νν΄ λμμ±μ μ ννκ³ μμ΄μ ν λνΈ λ³λ‘ μ μΌν Message Group IDλ₯Ό μμ±νλλ‘ μ μ΄νλ©΄ κ·Έλ° λ¬Έμ λ μμμ΅λλ€.
κ·Έλ κ² λλ€ λ 벨μμμ λΆμ°λ½μ νλνλ λ‘μ§μ μ κ±°νκ³ ν¨κ³Όμ μΌλ‘ λΉμ© μ΅μ νλ₯Ό λ¬μ±ν μ μμμ΅λλ€. λ€λ§ μ΄λ₯Ό λμ νλ κ³Όμ μμλ λ¬Έμ λ μ‘΄μ¬νμ΅λλ€.
κ³ μ λ Visibility Timeoutκ³Ό FIFO Queue λ¬Έμ
SQSμ λλ€λ₯Ό λΆμΌ λ κ³ λ €ν΄μΌλλ μ€μ μ€ νλλ Visibility Timeoutμ λλ€. Visibility Timeoutμ΄λ μλ κ·Έλ¦Όκ³Ό κ°μ΄, λλ€μμ SQS λ©μμ§λ₯Ό μμ ν μ΄ν μμ λΆν° ν΄λΉ λ©μμ§κ° λ€λ₯Έ λλ€μ μν΄ κ°μ Έκ°μ§ μ μλ μμ μ 컨νΈλ‘€νλλ° μ΄μ©λ©λλ€. λλ€μμ λ©μμ§λ₯Ό μμ νλ€κ³ SQSμμ λ©μμ§κ° λΉΌλ΄μ΄μ§λ κ²μ΄ μλ, λλ€κ° λ©μμ§λ₯Ό μ μμ μΌλ‘ μ²λ¦¬νμ§ λͺ»νλ μΌμ΄μ€λ₯Ό μν΄ μΌλ¨μ ν λ΄λΆμ λ¨κ²¨λλ λ€λ₯Έ λλ€μκ² λ³΄μ¬μ§λλ°κΉμ§λ μκ°μ΄ 걸리λ κ²μΌλ‘ μ΄ν΄νλ©΄ λ©λλ€.
μ΄ λ λλ€μ μ΅λ νμμμμ 15λΆμ΄κΈ° λλ¬Έμ, Visibility Timeout μμ 15λΆ μ΄μμΌλ‘ μ‘μμ€μΌν©λλ€. (λ¬Όλ‘ λλ€μ μ€ν μκ°μ μ νν μ μ μλ€λ©΄ κ·Έλ³΄λ€ μ§§μμ§ μ μκ² μΌλ DB IOκ° νμν μμ μ΄λΌλ©΄ μ£λΆλ¦¬ μμΈ‘νκΈ° μ΄λ ΅μ΅λλ€.) μ΄κ² μΌλ° SQS Queueμμλ λ¨μ§ ν΄λΉ λ©μμ§ μ²λ¦¬λ§ μ§μ°μ΄ λλ λ¬Έμ λ‘ μ΄μ΄μ§μ§λ§ FIFO Queueμμλ μ΄μΌκΈ°κ° λ€λ¦ λλ€.
μμ μ΄μΌκΈ°νλ― FIFO Queue λ΄λΆμλ Message Groupμ΄ μ‘΄μ¬νκ³ μ΄ κ·Έλ£Ή λ³λ‘ λλ€ λμμ±μ μ격ν μ νν©λλ€. λν λλ€μμ λ©μμ§λ₯Ό μμ νλλΌλ κ·Έ μ¦μ νμμ λΉΌλ΄μ§λ μλλ€κ³ μ΄μΌκΈ° νμμ΅λλ€. κ·Έλ° μν©μμ λλ€κ° μμνμ§ λͺ»ν λ¬Έμ λ‘ μΈν΄ λΉμ μμ μΌλ‘ λμνκ² λλ€λ©΄, Visibility Timeout μ€μ κ³Ό λ§λ¬Όλ € ν΄λΉ Message Groupμ Visibility Timeoutμ΄ λ°μνκ³ ν΄λΉ λ©μμ§κ° λ€μ μ μμ μΌλ‘ μ²λ¦¬λ λκΉμ§ κ·Έ μ΄ν λͺ¨λ λ©μμ§κ° μ§μ°λκ² λ©λλ€.
Visibility Timeout λ¬Έμ μ ν΄κ²°
λ€ννλ AWS SQSλ ChangeMessageVisibility 컀맨λλ₯Ό ν΅ν΄ νΉμ λ©μμ§ λ¨μλ‘ Visibility Timeout κ°μ λ³κ²½νλ κ²μ΄ κ°λ₯ν©λλ€.
νΈλ€λ¬ λ‘μ§ μ 체μ try-catchλ₯Ό κ±Έμ΄μ£Όκ³ μλ¬λ₯Ό μΊμΉνλ λΆλΆμμ ChangeMessageVisibility 컀맨λλ₯Ό μ€ν ν λλ€λ₯Ό μ’ λ£μν΅λλ€. κ·Έλ κ² λλ©΄ FIFO Queueμμ νΉμ λ©μμ§κ° μ€ν¨νλλΌλ, ν΄λΉ λ©μμ§λ μ΄ν λ©μμ§λ€μ μ²λ¦¬λ₯Ό λ§μ§ μκ³ λΉ λ₯΄κ² μ¬μλ νΉμ DLQλ‘ μ λ¬λ κ²μ λλ€.
μλλ NodeJSλ‘ μμ±λ μμμ λλ€.
export const handler: SQSHandler = async event => {
for (const record of event.Records) {
try {
// λ©μμ§ μ²λ¦¬ λ‘μ§
} catch (err) {
const sqsClient = new SQSClient({
...SQS Clientλ₯Ό μν μ€μ μΆκ°
})
await sqsClient.send(
new ChangeMessageVisibilityCommand({
QueueUrl: 'your-queue-url',
ReceiptHandle: record.receiptHandle,
VisibilityTimeout: 5, // 5μ΄ λ€ λ€μ λλ€μ μ λ¬λ¨
}),
)
throw err
}
}
}