ํ”ผ๋“œ๋กœ ๋Œ์•„๊ฐ€๊ธฐ
Defeating Webhook Storms: Idempotency in Laravel ๐Ÿ›‘
Dev.toDev.to
Backend

Redis Atomic Lock ๊ธฐ๋ฐ˜ Idempotency ๊ตฌํ˜„์„ ํ†ตํ•œ ์ค‘๋ณต ๊ฒฐ์ œ ๋ฐ ๋ฐ์ดํ„ฐ ์˜ค์—ผ ์›์ฒœ ์ฐจ๋‹จ

Defeating Webhook Storms: Idempotency in Laravel ๐Ÿ›‘

Prajapati Paresh2026๋…„ 6์›” 20์ผ3๋ถ„intermediate

Context

๋ถ„์‚ฐ ์‹œ์Šคํ…œ ํ™˜๊ฒฝ์—์„œ Webhook ์ „์†ก ์‹œ ๋ฐœ์ƒํ•˜๋Š” Network Latency์™€ Vendor์˜ Retry ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ์ธํ•œ ์ค‘๋ณต ์ฒ˜๋ฆฌ ์œ„ํ—˜ ์กด์žฌ. ํŠนํžˆ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด Vendor์˜ Timeout ์ž„๊ณ„์น˜(3์ดˆ)๋ฅผ ์ดˆ๊ณผํ•  ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๋Š” ์ค‘๋ณต ๊ณผ๊ธˆ ๋ฐ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ํŒŒ๊ดด ๋ฌธ์ œ ํ•ด๊ฒฐ ํ•„์š”.

Technical Solution

  • Vendor ์ œ๊ณต ๊ณ ์œ  Event ID๋ฅผ Idempotency Key๋กœ ํ™œ์šฉํ•˜์—ฌ ์š”์ฒญ์˜ ์œ ์ผ์„ฑ ์‹๋ณ„
  • API Controller์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ Queue Worker๋กœ ์œ„์ž„ํ•˜์—ฌ ์‘๋‹ต ์‹œ๊ฐ„์„ 50ms ๋ฏธ๋งŒ์œผ๋กœ ๋‹จ์ถ•ํ•˜๊ณ  Timeout ๋ฐฉ์ง€
  • Redis์˜ Atomic Lock์„ ํ†ตํ•ด ๋™์ผ Event ID์— ๋Œ€ํ•œ ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ค‘๋ณต ์‹คํ–‰ ์›์ฒœ ์ฐจ๋‹จ
  • ์ฒ˜๋ฆฌ ์™„๋ฃŒ๋œ Event ID๋ฅผ ์บ์‹œ์— 30์ผ๊ฐ„ ๊ธฐ๋กํ•˜์—ฌ ์žฅ๊ธฐ์ ์ธ ๊ด€์ ์˜ ์ค‘๋ณต ์š”์ฒญ ํ•„ํ„ฐ๋ง ๊ตฌ์กฐ ์„ค๊ณ„
  • Try-Catch ๋ธ”๋ก ๋‚ด Lock Release ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ตฌํ˜„ํ•˜์—ฌ ๋กœ์ง ์‹คํŒจ ์‹œ์—๋งŒ Retry๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ฐ€์šฉ์„ฑ ํ™•๋ณด

1. ์™ธ๋ถ€ API ์—ฐ๋™ ์‹œ Vendor๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ณ ์œ  ID๋ฅผ Idempotency Key๋กœ ์‚ฌ์šฉํ•˜๋Š”์ง€ ํ™•์ธ

2. ๋ฌด๊ฑฐ์šด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ API ์‘๋‹ต ๊ฒฝ๋กœ์—์„œ ๋ถ„๋ฆฌํ•˜์—ฌ Queue ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„

3. ๋ถ„์‚ฐ ๋ฝ(Distributed Lock) ์ ์šฉ ์‹œ ์ฒ˜๋ฆฌ ์‹คํŒจ ์ƒํ™ฉ์— ๋Œ€๋น„ํ•œ Lock Release ์ „๋žต ์ˆ˜๋ฆฝ

4. ์ฒ˜๋ฆฌ ์™„๋ฃŒ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” TTL(Time-To-Live) ๊ธฐ๊ฐ„์„ ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž์ถฐ ์„ค์ •

์›๋ฌธ ์ฝ๊ธฐ