Web Programming

슀마트 μŠ€ν† μ–΄μ˜ 동적 API 호좜 ν—ˆμš©λŸ‰ μ œν•œ 방법 - 토큰 버킷 μ•Œκ³ λ¦¬μ¦˜

ν”„λ‘œκ·Έλž˜λ¨Έ μ˜€μ›” 2025. 12. 27.

πŸš©κ°œμš”

사내 ERP μ„œλΉ„μŠ€μ— μ—¬λŸ¬ μ‡Όν•‘λͺ° κΈ°λŠ₯을 μ—°λ™ν•˜λŠ” κ°œμ„  μž‘μ—…μ„ μ§„ν–‰ν•˜λ˜ 쀑, ν•œ κ°€μ§€ νŠΉμ΄ν•œ 점을 λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. μ—¬λŸ¬ μ‡Όν•‘λͺ° κ°€μš΄λ°μ—μ„œλ„ λ„€μ΄λ²„μ˜ μŠ€λ§ˆνŠΈμŠ€ν† μ–΄ μ—°λ™μ—μ„œλ§Œ μœ λ… μ‹€νŒ¨ 응닡이 λΉˆλ²ˆν•˜κ²Œ λ°œμƒν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
응닡 λ©”μ‹œμ§€λŠ” λŒ€λΆ€λΆ„ λ™μΌν–ˆμŠ΅λ‹ˆλ‹€.

“ν• λ‹Ήλœ μ‹œκ°„λ‹Ή μš”μ²­λŸ‰μ„ μ΄ˆκ³Όν•˜μ˜€μŠ΅λ‹ˆλ‹€.”

 


저희 μ„œλΉ„μŠ€μ—μ„œλŠ” μ΄λŸ¬ν•œ μ‹€νŒ¨ 건을 λ‹¨μˆœ 였λ₯˜λ‘œ μ²˜λ¦¬ν•˜κ³ , μ‚¬μš©μžμ—κ²Œ “μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄ 달라”λŠ” μ•ˆλ‚΄λ§Œ μ œκ³΅ν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

μ €λŠ” μ‹€νŒ¨ λΉˆλ„κ°€ 반볡적으둜 λ°œμƒν•˜λŠ” 점이 λ‹¨μˆœν•œ μΌμ‹œμ  μž₯μ• λ‘œ λ³΄κΈ°μ—λŠ” μ΄μƒν•˜λ‹€λŠ” 생각이 λ“€μ—ˆμŠ΅λ‹ˆλ‹€.

 

원인을 μΆ”적해본 κ²°κ³Ό, λ¬Έμ œλŠ” μ„œλ²„ μž₯μ• κ°€ μ•„λ‹ˆλΌ ν˜ΈμΆœ λ°©μ‹ μžμ²΄μ— μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
λ„€μ΄λ²„μ˜ μŠ€λ§ˆνŠΈμŠ€ν† μ–΄λŠ” API 호좜 ν—ˆμš©λŸ‰μ„ λ™μ μœΌλ‘œ μ œν•œν•˜κ³  μžˆμ—ˆμ§€λ§Œ, 저희 μ‹œμŠ€ν…œμ€ ν•΄λ‹Ή μ œν•œμ„ κ³ λ €ν•˜μ§€ μ•Šμ€ 채 μš”μ²­μ„ μ§€μ†μ μœΌλ‘œ μ „μ†‘ν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€. κ·Έ κ²°κ³Ό μŠ€λ§ˆνŠΈμŠ€ν† μ–΄ μ„œλ²„ μΈ‘μ—μ„œλŠ” 정상적인 λ°©μ–΄ λ‘œμ§μ— 따라 429(Too Many Requests) 응닡을 λ°˜ν™˜ν–ˆκ³ , 저희 μ„œλΉ„μŠ€λŠ” 이λ₯Ό μ‹€νŒ¨λ‘œ μ²˜λ¦¬ν•  μˆ˜λ°–μ— μ—†μ—ˆλ˜ κ²ƒμž…λ‹ˆλ‹€.

 


ν•΄κ²° λ°©λ²•은 μ˜μ™Έλ‘œ λ‹¨μˆœν–ˆμŠ΅λ‹ˆλ‹€.
μŠ€λ§ˆνŠΈμŠ€ν† μ–΄ API 호좜 μ‹œ μ œκ³΅λ˜λŠ” 호좜 ν—ˆμš©λŸ‰ 정보λ₯Ό κΈ°μ€€μœΌλ‘œ, 남은 호좜 κ°€λŠ₯ νšŸμˆ˜κ°€ 없을 경우 μš”μ²­μ„ μž μ‹œ λŒ€κΈ°(sleep)μ‹œν‚¨ λ’€ λ‹€μŒ μ‹œκ°„ ꡬ간에 λ‹€μ‹œ μš”μ²­ν•˜λ„λ‘ 흐름을 μ‘°μ •ν–ˆμŠ΅λ‹ˆλ‹€. 이 κ°œμ„ λ§ŒμœΌλ‘œλ„ μ΄μ „κΉŒμ§€ λΉˆλ²ˆν•˜κ²Œ λ°œμƒν•˜λ˜ API 호좜 μ‹€νŒ¨κ°€ 거의 λͺ¨λ‘ μ‚¬λΌμ‘Œκ³ , μ‚¬μš©μž κ²½ν—˜ μ—­μ‹œ λˆˆμ— λ„κ²Œ μ•ˆμ •ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

 

이번 μž‘μ—…μ„ 톡해 μ €λŠ” 넀이버 μŠ€λ§ˆνŠΈμŠ€ν† μ–΄κ°€ '토큰 버킷 μ•Œκ³ λ¦¬μ¦˜(Token Bucket Rate Limiting Algorithm)' 을 기반으둜 ν•œ 동적 API 호좜 ν—ˆμš©λŸ‰ μ œν•œ 방식에 μ£Όλͺ©ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이런 κΈ°λŠ₯은 λ‹¨μˆœν•œ “μ œν•œ μ •μ±…”이 μ•„λ‹ˆλΌ, Open APIλ₯Ό μ œκ³΅ν•˜λŠ” ν”Œλž«νΌμ΄ λ‹€μˆ˜μ˜ ν΄λΌμ΄μ–ΈνŠΈλ‘œλΆ€ν„° μ„œλ²„λ₯Ό λ³΄ν˜Έν•˜κΈ° μœ„ν•œ 맀우 ν˜„μ‹€μ μ΄κ³  κ²€μ¦λœ μ„€κ³„λΌλŠ” 점을 λŠκΌˆμŠ΅λ‹ˆλ‹€.

 

 

κ·Έλž˜μ„œ 이번 κΈ€μ—μ„œλŠ” 넀이버 μŠ€λ§ˆνŠΈμŠ€ν† μ–΄μ˜ 동적 API 호좜 ν—ˆμš©λŸ‰ μ œν•œ 방식을 μ‚΄νŽ΄λ³΄λ©΄μ„œ, 토큰 버킷 μ•Œκ³ λ¦¬μ¦˜μ΄ 무엇인지, 그리고 λ§Œμ•½ λ‚΄κ°€ μ΄ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ” μž…μž₯이라면 μ–΄λ–»κ²Œ μ„€κ³„ν•˜κ³  κ΅¬ν˜„ν•  κ²ƒμΈμ§€λ₯Ό μ€‘μ‹¬μœΌλ‘œ μ •λ¦¬ν•΄λ³΄κ³ μž ν•©λ‹ˆλ‹€.

 

 

 

동적 호좜 ν—ˆμš©λŸ‰ μ œν•œ”이 ν•„μš”ν•΄μ§„ 이유

APIλ₯Ό μš΄μ˜ν•˜λŠ” μž…μž₯μ—μ„œ κ°€μž₯ λ¬΄μ„œμš΄ μˆœκ°„μ€ 두 κ°€μ§€μž…λ‹ˆλ‹€.

  • μ˜ˆμƒ κ°€λŠ₯ν•œ 폭주
    예: μ˜€μ „ 10μ‹œ μ΄ν›„ μ£Όλ¬Έμ΄ κΈ‰μ¦, λ°œμ£Ό λ§ˆκ° μ‹œκ°„, λŒ€κ·œλͺ¨ ν”„λ‘œλͺ¨μ…˜, λͺ…μ ˆ μ‹œμ¦Œ λ“±.

  • μ˜ˆμƒ λΆˆκ°€λŠ₯ν•œ 폭주
    예: νŠΉμ • μ†”λ£¨μ…˜ λ²„κ·Έλ‘œ λ¬΄ν•œ μž¬μ‹œλ„, μž₯μ•  μƒν™©μ—μ„œ μž¬μ‹œλ„ 폭발(thundering herd), 배치 μž‘μ—…μ΄ ν•œ μ‹œκ°μ— λ™μ‹œμ— μ‹€ν–‰.


μ΄λ•Œ μ„œλ²„λŠ” λ‹¨μˆœνžˆ “CPUκ°€ λ°”μ˜λ‹€” μˆ˜μ€€μ΄ μ•„λ‹ˆλΌ, DB 컀λ„₯μ…˜ ν’€ 고갈, μŠ€λ ˆλ“œ/μ΄λ²€νŠΈλ£¨ν”„ μž μ‹, μΊμ‹œ 미슀 증가, 큐 κ³ΌλΆ€ν™”, νƒ€μž„μ•„μ›ƒ μ—°μ‡„λ‘œ μ΄μ–΄μ§‘λ‹ˆλ‹€. 더 μœ„ν—˜ν•œ 건, 폭주가 ν•œ μ‚¬μš©μž(λ˜λŠ” ν•œ μ†”λ£¨μ…˜)μ—μ„œ μ‹œμž‘ν•΄λ„ κ²°κ³ΌλŠ” ν”Œλž«νΌ 전체 μ‚¬μš©μžμ—κ²Œ ν™•μ‚°λœλ‹€λŠ” μ μž…λ‹ˆλ‹€. κ·Έλž˜μ„œ ν”Œλž«νΌμ€ “정상 μ‚¬μš©μž 보호”λ₯Ό μœ„ν•΄μ„œλΌλ„ κ°•μ œμ μΈ μ œν•œ μž₯μΉ˜κ°€ ν•„μš”ν•©λ‹ˆλ‹€.

 


λ˜ν•œ μ—¬κΈ°μ„œ μ€‘μš”ν•œ ν˜„μ‹€μ΄ ν•˜λ‚˜ μžˆμŠ΅λ‹ˆλ‹€. APIλŠ” “평균 μ²˜λ¦¬λŸ‰”λ§ŒμœΌλ‘œλŠ” μ•ˆμ „ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ‹€μ œ μž₯μ• λŠ” “μˆœκ°„ 피크(λ²„μŠ€νŠΈ)”와 “μ—°μ†λœ μž¬μ‹œλ„”μ—μ„œ λ°œμƒν•©λ‹ˆλ‹€.
즉, ν”Œλž«νΌμ€ ν‰κ· μ μœΌλ‘œλŠ” μΆ©λΆ„νžˆ 처리 κ°€λŠ₯해도, “1초 사이에 λͺ°λ¦¬λŠ” μš”μ²­”을 μ œμ–΄ν•΄μ•Ό ν•©λ‹ˆλ‹€.

이 문제λ₯Ό ν’€κΈ° μœ„ν•œ λŒ€ν‘œμ μΈ 방법이 토큰 버킷 μ•Œκ³ λ¦¬μ¦˜μž…λ‹ˆλ‹€.

 

 

 

 

πŸͺ£ν† ν° 버킷 μ•Œκ³ λ¦¬μ¦˜

토큰 버킷은 λ„€νŠΈμ›Œν¬ νŠΈλž˜ν”½ μ œμ–΄ λΆ„μ•Όμ—μ„œ μˆ˜μ‹­ λ…„κ°„ μ‚¬μš©λΌ 온 Rate Limiting μ•Œκ³ λ¦¬μ¦˜μž…λ‹ˆλ‹€.

  • λ“±μž₯ λ°°κ²½: λ„€νŠΈμ›Œν¬ QoS(Quality of Service), νŠΈλž˜ν”½ 쉐이핑
  • λͺ©μ : 평균 μ²˜λ¦¬μœ¨μ€ μ œν•œν•˜λ©΄μ„œ, μˆœκ°„μ μΈ burstλŠ” ν—ˆμš©
  • μ‚¬μš© λΆ„μ•Ό:λΌμš°ν„° / μŠ€μœ„μΉ˜ νŠΈλž˜ν”½ μ œμ–΄, OS λ„€νŠΈμ›Œν¬ μŠ€νƒ, API Gateway / Reverse Proxy

 

토큰 버킷(Token Bucket)의 어원을 보면 버킷(bucket)은 토큰을 λ‹΄μ•„λ‘λŠ” μ €μž₯ 곡간이고, 토큰(token)은 μš”μ²­ 1건을 μ²˜λ¦¬ν•  수 μžˆλŠ” κΆŒν•œμ„ λ§ν•©λ‹ˆλ‹€. 

 

λ™μž‘ μ›λ¦¬λŠ” 맀우 λ‹¨μˆœν•©λ‹ˆλ‹€.

  1. 버킷에 토큰이 일정 μ†λ„λ‘œ μ±„μ›Œμ§ (예: μ΄ˆλ‹Ή 10개)
  2. μš”μ²­ 1κ°œλ‹Ή 토큰 1개 μ†ŒλΉ„
  3. 토큰이 μ—†μœΌλ©΄ μš”μ²­ 거절 (429)
  4. λ‹€μŒ 토큰 수만큼 κ°€λΆˆν•΄μ„œ μ‚¬μš© κ°€λŠ₯ → burst ν—ˆμš©(λŒ€μ‹  μ—°μ†μ μœΌλ‘œ μ‚¬μš©μ€ λΆˆκ°€)

 

토큰 버킷(Token Bucket) μ•Œκ³ λ¦¬μ¦˜μ΄ “API 호좜 μ œν•œ”에 잘 λ§žλŠ” μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

(1) μ΄ˆλ‹Ή μ²˜λ¦¬λŸ‰μ„ λͺ…ν™•ν•˜κ²Œ “μ •μ˜”ν•  수 μžˆλ‹€.
토큰이 μ΄ˆλ‹Ή N개 μ±„μ›Œμ§€λ©΄, μ‹œμŠ€ν…œμ€ μ΄ˆλ‹Ή N개 μˆ˜μ€€μœΌλ‘œ μš”청을 μ•ˆμ •μ μœΌλ‘œ μ²˜λ¦¬ν•˜κ²Œ λ©λ‹ˆλ‹€. μ„œλ²„ μž…μž₯μ—μ„œλŠ” λ¦¬μ†ŒμŠ€ μ‚¬μš©λŸ‰ μƒν•œμ„ μ„ λ§Œλ“€ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

(2) 짧은 λ²„μŠ€νŠΈλ₯Ό “μœ μ—°ν•˜κ²Œ” 받아쀄 수 μžˆλ‹€.
ν˜„μ‹€ νŠΈλž˜ν”½μ€ μΌμ •ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ν† ν°μ΄ μŒ“μ—¬ μžˆλ‹€λ©΄ μˆœκ°„μ μœΌλ‘œ λͺ‡ κ°œ λ” μ²˜λ¦¬ν•΄λ„ μ „체 μ•ˆμ •성에 ν° λ¬Έμ œκ°€ μ—†μŠ΅λ‹ˆλ‹€. μ΄λŸ° “짧은 κΈ‰μ¦”을 ν—ˆμš©ν•˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈ μ²΄κ° μ„±λŠ₯도 μ’‹μ•„μ§‘λ‹ˆλ‹€.

(3) 거절(HTTP 429)을 “μ •μ±…μ μœΌλ‘œ” μΌκ΄€λ˜κ²Œ λ§Œλ“€ 수 μžˆλ‹€.
"이 API에 λ‹Ήμ‹ μ˜ 토큰이 μ—†μœΌλ©΄ 거절". μ΄μœ κ°€ λͺ…ν™•ν•©λ‹ˆλ‹€.
이 일관성이 ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œλ„ μ€‘μš”ν•©λ‹ˆλ‹€. μ• λ§€ν•˜κ²Œ νƒ€μž„μ•„μ›ƒμœΌλ‘œ μ£½λŠ” 것보닀, “λ„ˆ μ§€κΈˆ λ„ˆλ¬΄ 많이 λ³΄λƒˆλ‹€(429)”κ°€ 훨씬 μ„€κ³„ν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€.


슀마트 μŠ€ν† μ–΄μ˜ 컀머슀API ν”Œλž«νΌμ€ λ°”λ‘œ μ΄ ν† ν° λ²„ν‚· κΈ°λ°˜μœΌλ‘œ ν˜ΈμΆœλŸ‰μ„ ν†΅μ œν•©λ‹ˆλ‹€.

 

 

 

πŸš€μŠ€λ§ˆνŠΈ μŠ€ν† μ–΄μ˜ λ™μ  API ν˜ΈμΆœ ν—ˆμš©λŸ‰ μ œν•œ λ°©λ²•

슀마트 μŠ€ν† μ–΄ 컀머슀API ν”Œλž«νΌμ€ μŠ€λ§ˆνŠΈμŠ€ν† μ–΄ 판맀자, μ»€λ¨ΈμŠ€μ†”λ£¨μ…˜ κ΅¬λ…μž λ“± λ‹€μ–‘ν•œ μ‚¬μš©μž λΆ„λ“€κ»˜ μ„œλΉ„μŠ€λ₯Ό μ œκ³΅ν•˜λŠ” λ²”μš© API ν”Œλž«νΌμž…λ‹ˆλ‹€.
μ•ˆμ •μ  μ„œλΉ„μŠ€ μ œκ³΅μ„ μœ„ν•΄ λͺ¨λ“  API μ‚¬μš©μžμ—κ²Œ μ‹œκ°„λ‹Ή μ΅œλŒ€ API 호좜 횟수 μ œν•œμ„ 빠짐없이 μ μš©ν•˜μ—¬ νŠΉμ • μ‚¬μš©μžκ°€ μ‹œμŠ€ν…œ μžμ›μ„ 과점할 수 없도둝 섀계돼 μžˆλ‹€κ³  ν•©λ‹ˆλ‹€.

 

 

슀마트 μŠ€ν† μ–΄ 컀머슀APIλŠ” '토큰 버킷 μ•Œκ³ λ¦¬μ¦˜Token Bucket Rate Limiting Algorithm'을 μ μš©ν•˜μ—¬ API ν˜ΈμΆœλŸ‰μ„ μ œν•œν•©λ‹ˆλ‹€.
각 κ³„μΈ΅λ³„λ‘œ 1초 λ™μ•ˆ μ²˜λ¦¬κ°€ κ°€λŠ₯ν•œ API ν˜ΈμΆœ νšŸμˆ˜λ₯Ό μ •ν•˜μ—¬ ν•΄λ‹Ή νšŸμˆ˜λ₯Ό μ΄ˆκ³Όν•˜λŠ” API μš”청은 μ²˜λ¦¬ λΆˆκ°€ μ‘닡을 λ°˜ν™˜ν•©λ‹ˆλ‹€. μ΄λ•Œ νŠΉμ • κ³„측에 ν˜ΈμΆœ νšŸμˆ˜κ°€ λ‚¨μ•„μžˆλ”λΌλ„ μƒμœ„ κ³„μΈ΅μ˜ ν˜ΈμΆœ νšŸμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆλ‹€λ©΄ μ²˜λ¦¬ λΆˆκ°€ μ‘닡을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

 

컀머슀API ν”Œλž«νΌμ—μ„œ 호좜 횟수 μ‚°μ • 계측은 μ•„λž˜μ˜ μš°μ„  μˆœμœ„λ₯Ό κΈ°μ€€μœΌλ‘œ ν•©λ‹ˆλ‹€.

  1. API μˆ˜μš©λŸ‰
  2. μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ³„ 호좜 ν—ˆμš©λŸ‰ – Rate limit
  3. SELLER 토큰별 호좜 ν—ˆμš©λŸ‰ – Quota limit

좜처 : 넀이버 - https://github.com/commerce-api-naver/commerce-api/discussions/6

 

APIλŒ€ν–‰μ‚¬μ˜ λ™μ  ν˜ΈμΆœ ν—ˆμš©λŸ‰ μ„€μ • μ‹œ ν˜ΈμΆœλŸ‰ μ‚°μ •은 β‘  μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 별 μ‚°μ •(Rate limit), β‘‘ μŠ€ν† μ–΄ 계정 별 μ‚°μ •(Quota limit) μ΄μ€‘μœΌλ‘œ μ μš©λ©λ‹ˆλ‹€.

  • Rate limit: κΈ°μ‘΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 1κ°œλ³„ ν—ˆμš©ν•˜λŠ” 호좜 μ΄λŸ‰
  • Quota limit: 'SELLER νƒ€μž…' 인증 토큰 1κ°œλ³„ ν—ˆμš©ν•˜λŠ” 호좜 μ΄λŸ‰

μ†”λ£¨μ…˜/APIλŒ€ν–‰μ‚¬λ§ˆλ‹€ λ‹€λ₯Έ 호좜 ν—ˆμš©λŸ‰μ„ μ œκ³΅λ°›μŠ΅λ‹ˆλ‹€.(즉, 같은 API이더라도 μ†”λ£¨μ…˜/APIλŒ€ν–‰μ‚¬λ³„λ‘œ λ‹€λ₯Έ 호좜 ν—ˆμš©λŸ‰(토큰 수)이 λ‹€λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€.)

 

 

1️⃣API μˆ˜μš©λŸ‰

API μˆ˜μš©λŸ‰μ€ “νŠΉμ • APIκ°€ 전체 μ‚¬μš©μž λŒ€μƒμœΌλ‘œ 1μ΄ˆμ— μ²˜λ¦¬ν•  수 μžˆλŠ” μ΄λŸ‰”μž…λ‹ˆλ‹€.
API μˆ˜μš©λŸ‰μ€ κ° API별 κΈ°λŠ₯ νŠΉμ„±κ³Ό κΈ°μˆ  μ‚¬μ–‘에 λ”°λΌ κ°κΈ° λ‹€λ₯Έ μˆ˜μš©λŸ‰μœΌλ‘œ μ„€μ •ν•©λ‹ˆλ‹€. API μˆ˜μš©λŸ‰μ€ μ„œλΉ„μŠ€ μš΄μš© μƒν™©μ— λ”°λΌ μœ λ™μ μΌ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

API μˆ˜μš©λŸ‰μ„ μ΄ˆκ³Όν•˜λŠ” ν˜ΈμΆœ μš”청에 λŒ€ν•΄μ„œλŠ” HTTP 429 μ‘닡을 λ°˜ν™˜ν•©λ‹ˆλ‹€. μ΄λ•Œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ³„ ν˜ΈμΆœ ν—ˆμš©λŸ‰(Rate limit)이 λ‚¨μ•„μžˆλŠ”μ§€λŠ” κ³ λ €ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

 

 

ν”Œλž«νΌμ΄ μ •말 μœ„ν—˜ν•œ μˆœκ°„μ—λŠ” “λ„ˆλŠ” μ•„직 μΏΌν„° λ‚¨μ•˜μœΌλ‹ˆ μ²˜λ¦¬ν•΄μ€„κ²Œ” κ°™μ€ μ—¬μœ κ°€ μ—†μŠ΅λ‹ˆλ‹€. μ„œλ²„κ°€ λ²„ν‹°λ €λ©΄ μ „체 μƒν•œμ„ μ„ λ¨Όμ € μ§€μΌœμ•Ό ν•©λ‹ˆλ‹€.
즉, API μˆ˜μš©λŸ‰μ€ “전체 생쑴”을 μœ„ν•œ μ΅œν›„μ˜ μ•ˆμ „μž₯μΉ˜μž…λ‹ˆλ‹€.

 

2οΈβƒ£μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ³„ 호좜 ν—ˆμš©λŸ‰ – Rate limit

'μ• ν”Œλ¦¬μΌ€μ΄μ…˜'은 컀머슀API ν”Œλž«νΌμ— APIλ₯Ό ν˜ΈμΆœν•  λ•Œ ν•„μš”ν•œ 자격 증λͺ… 정보 μ„ΈνŠΈ(μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ID/Secret)μž…λ‹ˆλ‹€.(λ‹€μ‹œ 말해 νŠΉμ • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν•˜λ‚˜ν•˜λ‚˜λ₯Ό λœ»ν•©λ‹ˆλ‹€.) νŠΉμ • API의 호좜 ν—ˆμš©λŸ‰ 초과 μ—¬λΆ€ νŒλ‹¨μ€ λŒ€μƒ API에 λŒ€ν•œ μ‹œκ°„ ꡬ간(1초 λ²”μœ„) λ‚΄ 호좜 횟수λ₯Ό κΈ°μ€€μœΌλ‘œ ν•˜λ©° μ΄λ•Œ 횟수 산정은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‹¨μœ„λ‘œ μΈ‘μ •ν•©λ‹ˆλ‹€.
μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‹¨μœ„μ—μ„œ νŠΉμ • API에 λŒ€ν•œ 1μ΄ˆλ‹Ή ν˜ΈμΆœ κ°€λŠ₯ νšŸμˆ˜(호좜 ν—ˆμš©λŸ‰)λ₯Ό "Rate limit" μ΄λΌ λΆ€λ¦…λ‹ˆλ‹€.

Rate limit을 μ΄ˆκ³Όν•˜λŠ” ν˜ΈμΆœ μš”청에 λŒ€ν•΄μ„œλŠ” HTTP 429 μ‘닡을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

이런 μ œν•œμ μ€ ν•œ μ†”λ£¨μ…˜μ΄ λ²„κ·Έλ‘œ ν•œ APIλ₯Ό 폭주 ν˜ΈμΆœν•΄λ„, κ·Έ μ•±λ§Œ μ œν•œμ— 걸리고 λ‹€λ₯Έ μ•±μ—λŠ” 영ν–₯이 μ€„μ–΄λ“­λ‹ˆλ‹€.
λ˜ν•œ, μ•± λ‹¨μœ„λ‘œ 곡정성도 ν™•λ³΄λ©λ‹ˆλ‹€.

 

3️⃣Burst Max

Burst MaxλŠ” λ‹€μŒ 1초의 Rate limit을 μ•žλ‹Ήκ²¨ λΉŒλ €μ˜΅λ‹ˆλ‹€.
컀머슀API ν”Œλž«νΌμ—μ„œλŠ” λŒ€μƒ μ‹œκ°„ λ²”μœ„(1초) λ‚΄ λ‚¨μ€ Rate limit을 μ΄ˆκ³Όν•˜λŠ” API μš”청이 λ°œμƒν•  κ²½μš° μžλ™μœΌλ‘œ Burst Max κΈ°λŠ₯을 ν™œμ„±ν™”ν•˜μ—¬ λ‹€μŒ 1초 κ΅¬κ°„μ˜ Rate limit을 μ•žλ‹Ήκ²¨ ν˜ΈμΆœ νšŸμˆ˜λ₯Ό μ‚°μ •ν•©λ‹ˆλ‹€.

단, Burst MaxλŠ” μ—°μ†ν•˜μ—¬ μ‚¬μš©ν•  μˆ˜ μ—†μŠ΅λ‹ˆλ‹€.

 

 

4️⃣SELLER 토큰별 호좜 ν—ˆμš©λŸ‰ - Quota limit

Quota limit은 'SELLER νƒ€μž…' 인증 토큰 1κ°œλ³„ ν—ˆμš©ν•˜λŠ” 호좜 μ΄λŸ‰μž…λ‹ˆλ‹€.(λ‹¨μœ„ μ‹œκ°„λ‹Ή[1초] 판맀자 λ¦¬μ†ŒμŠ€ μš”μ²­ 수 μ œν•œ)

Quota limit은 λŒ€μƒ λŒ€ν–‰μ‚¬ μ‹œμŠ€ν…œμ„ μ΄μš©ν•˜λŠ” νŠΉμ •ν•œ μ΅œμ’… μ‚¬μš©μž(판맀자)κ°€ ν• λ‹Ήλœ Rate limit을 κ³Όμ ν•˜μ—¬ λ‹€λ₯Έ μ΅œμ’… μ‚¬μš©μžμ˜ μ»€λ¨ΈμŠ€API ν˜ΈμΆœμ„ μ–΄λ ΅κ²Œ λ§Œλ“œλŠ” μΌμ„ μ™„ν™”ν•©λ‹ˆλ‹€.

Quota limit은 Rate limit에 λŒ€ν•œ 일정 λΉ„μœ¨λ‘œ μ‚°μ •λ©λ‹ˆλ‹€. λŒ€μƒ SELLER 인증 ν† ν°μœΌλ‘œλŠ” Quota limit을 μ΄ˆκ³Όν•˜λŠ” API 호좜이 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€. Quota limit에 μ μš©μ„ λ°›λŠ” SELLER μΈμ¦ ν† ν°λ“€μ˜ ν˜ΈμΆœ ν—ˆμš©λŸ‰ μ΄ν•©μ€ Rate limit을 μ΄ˆκ³Όν•  μˆ˜ μ—†μŠ΅λ‹ˆλ‹€.

 

 

πŸͺ§API별 ν˜ΈμΆœ ν—ˆμš©λŸ‰ ν™•인

각 API별 ν˜ΈμΆœ ν—ˆμš©λŸ‰μ€ API ν˜ΈμΆœμ— λŒ€ν•œ HTTP μ‘λ‹΅ ν—€λ”(Response header)둜 μ œκ³΅ν•©λ‹ˆλ‹€.

 

  • GNCP-GW-RateLimit-Replenish-Rate: κΈ°λ³Έ μ΄ˆλ‹Ή 호좜 ν—ˆμš©λŸ‰ 수
  • GNCP-GW-RateLimit-Burst-Capacity: λ²„μŠ€νŠΈ λ§₯슀(Burst Max)둜 처리 κ°€λŠ₯ν•œ μ΄ˆλ‹Ή 호좜 ν—ˆμš©λŸ‰ 수
  • GNCP-GW-RateLimit-Remaining: λ‚¨μ€ ν˜ΈμΆœ ν—ˆμš©λŸ‰ μˆ˜

  • GNCP-GW-Quota-Period: 호좜 ν—ˆμš©λŸ‰μ˜ λ‹¨μœ„ μ‹œκ°„(λŒ€ν–‰μ‚¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜: SECONDS κ°’μœΌλ‘œ κ³ μ •)
  • GNCP-GW-Quota-Limit: λŒ€μƒ SELLER 인증 ν† ν°μ˜ 호좜 ν—ˆμš©λŸ‰ 수
  • GNCP-GW-Quota-Remaining: λŒ€μƒ SELLER μΈμ¦ ν† ν°μ˜ λ‚¨μ€ ν˜ΈμΆœ ν—ˆμš©λŸ‰ μˆ˜

 

μ˜ˆμ‹œ 응닡

호좜 ν—ˆμš©λŸ‰μ„ μ΄ˆκ³Όν•˜λŠ” API 호좜 상황 (μ• ν”Œλ¦¬μΌ€μ΄μ…˜/SELLER 인증 토큰)

...μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ³„ 호좜 ν—ˆμš©λŸ‰μ΄ λ‹€ 된 경우 Remaining:"0"
GNCP-GW-RateLimit-Burst-Capacity:"4"
GNCP-GW-RateLimit-Replenish-Rate:"2"
GNCP-GW-RateLimit-Remaining:"0"

...SELLER 토큰별 호좜 ν—ˆμš©λŸ‰μ΄ λ‹€ 된 경우 Remaining:"0"
GNCP-GW-Quota-Period:"SECONDS"
GNCP-GW-Quota-Limit:"4"
GNCP-GW-Quota-Remaining:"0"
...

 

 

 

πŸ“μ˜ˆμ‹œ μΌ€μ΄μŠ€

λ¦¬μ†ŒμŠ€ μ„œλ²„μ—μ„œ μ œκ³΅ν•˜λŠ” Open API 쀑 "/abc/xyz/{id}" λΌλŠ” API κ°€ 있고, 이 API 그룹의 κΆŒν•œμ„ κ°–κ³  μžˆλŠ” λŒ€ν–‰μ‚¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ "A"κ°€ μžˆμŠ΅λ‹ˆλ‹€.

그리고 이 A μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‚¬μš©ν•˜λŠ” νŒλ§€μžλŠ” "μ΄μˆœμ‹ κ³Ό" "μ•ˆμ€‘κ·Ό" 2λͺ…이 μžˆμŠ΅λ‹ˆλ‹€.

각각 API μˆ˜μš©λŸ‰μ€ 10 / μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ³„ 호좜 ν—ˆμš©λŸ‰ – Rate limit은 4 / SELLER 토큰별 호좜 ν—ˆμš©λŸ‰ – Quota limit 은 2라고 κ°€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 

1️⃣ SELLER 토큰 별 호좜 ν—ˆμš©λŸ‰μ„ μ΄ˆκ³Όν•˜λŠ” 경우

1μ΄ˆλ‹Ή SELLER 토큰 별 호좜 ν—ˆμš©λŸ‰μ€ 2μž…λ‹ˆλ‹€. 1초 내에 μ•ˆμ€‘κ·Ό μ…€λŸ¬κ°€ μ„œλ“œ νŒŒν‹°μΈ A μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 톡해 /abc/xyz/{id} μš”μ²­μ„ 3 번 λ³΄λƒˆλ‹€κ³  κ°€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€. (Burst Max은 λ¬΄μ‹œ)

 

  1. 첫번째 μš”μ²­ 성곡 / RateLimit-Remaining : 3 / Quota-Remaining : 1
  2. λ‘λ²ˆμ§Έ μš”μ²­ 성곡/ RateLimit-Remaining : 2 / Quota-Remaining :0
  3. μ„Έλ²ˆμ§Έ μš”μ²­ μ‹€νŒ¨ / 429 응닡

 

μ΄λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 호좜 ν—ˆμš©λŸ‰μ΄ λ‚¨μ•˜λ‹€ ν•˜λ”λΌλ„ SELLER 토큰 별 호좜 ν—ˆμš©λŸ‰μ„ μ΄ˆκ³Όν•˜μ˜€κΈ° λ•Œλ¬Έμ— μš”μ²­μ— μ‹€νŒ¨ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

 

2️⃣ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 별 호좜 ν—ˆμš©λŸ‰μ„ μ΄ˆκ³Όν•˜λŠ” 경우

17μ‹œ 03μ΄ˆμ— A μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‚¬μš©μž μ•ˆμ€‘κ·Όκ³Ό μ΄μˆœμ‹ μ΄ λ§₯슀 ν—ˆμš©λŸ‰μΈ 2νšŒμ”© μš”μ²­μ„ λ³΄λƒˆλ‹€κ³  κ°€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€. μ΄λ•Œ λ„€νŠΈμ›Œν¬ μ§€μ—°μ΄λ‚˜ μž¬μ‹œλ„ 처리 λ“±μ˜ 이유둜 17μ‹œ 02.987 μ΄ˆμ— 보낸 μ•ˆμ€‘κ·Ό μš”μ²­μ΄ μ„œλ²„μ—λŠ” 03μ΄ˆμ— 도착할 수 μžˆμŠ΅λ‹ˆλ‹€.

A μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 호좜 ν—ˆμš©λŸ‰μ€ 4인데 03μ΄ˆμ— 총 5회의 μš”μ²­μ„ λ°›μ•˜κΈ° λ•Œλ¬Έμ—, 이 쀑 κ°€μž₯ λ§ˆμ§€λ§‰ μš”μ²­μ€ μ‹€νŒ¨ μ²˜λ¦¬λ©λ‹ˆλ‹€.

ν”Œλž«νΌμ€ “μˆœκ°„ μœ μž…λŸ‰” κΈ°μ€€μœΌλ‘œ Rateλ₯Ό κ³„μ‚°ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

 

μ΄λŠ” API 총 호좜 ν—ˆμš©λŸ‰μ΄ 10으둜 총 호좜 ν—ˆμš©λŸ‰μ€ λ‚¨μ•˜λ”λΌλ„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 별 호좜 ν—ˆμš©λŸ‰μ„ 초과 ν•˜μ˜€κΈ° λ•Œλ¬Έμ— μš”μ²­μ— μ‹€νŒ¨ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

 

3️⃣ API별 호좜 ν—ˆμš©λŸ‰μ„ μ΄ˆκ³Όν•˜λŠ” 경우

"/abc/xyz/{id}" API 의 총 호좜 ν—ˆμš©λŸ‰μ€ 10μž…λ‹ˆλ‹€. μ΄λ•Œ μ„œλΉ„μŠ€ 혼작 상황이고 A μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ‚¬μš©μž(판맀자)인 μ•ˆμ€‘κ·Ό, μ΄μˆœμ‹ μ΄ 각각 μš”μ²­μ„ ν•œλ²ˆλ§Œ 보낸 λ‹€κ³  κ°€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€. 

ν•˜μ§€λ§Œ A μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ§κ³ , B,C,D μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 각각 이번 초 ꡬ간에 3의 μš”μ²­μ„ 보낸 λ‹€κ³  ν•˜κ² μŠ΅λ‹ˆλ‹€.

μš”μ²­ μœ μž… μ‹œκ°„ μˆœμ„œλŠ” B → C → D μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‚¬μš©μž → A μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ•ˆμ€‘κ·Ό → A μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ΄μˆœμ‹ 

 

B,C,D μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μš”μ²­μ„ λͺ¨λ‘ ν—ˆμš©ν–ˆμœΌλ―€λ‘œ API 의 ν—ˆμš©λŸ‰μ€ 1μž…λ‹ˆλ‹€. A μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ•ˆμ€‘κ·Ό μš”μ²­μ€ ν—ˆμš© κ°€λŠ₯ν•˜λ―€λ‘œ μ„±κ³΅ν•©λ‹ˆλ‹€. κ·Έ λ‹€μŒ A  μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ΄μˆœμ‹ μ€ API별 호좜 ν—ˆμš©λŸ‰μ„ μ΄ˆκ³Όν•˜μ—¬ 429 응닡을 λ°›κ²Œ λ©λ‹ˆλ‹€.

 

 

 

 

πŸ€”ν† ν° 버킷 μ•Œκ³ λ¦¬μ¦˜μ„ ν™œμš©ν•˜μ—¬ 직접 κ΅¬ν˜„ν•΄ λ³Έλ‹€λ©΄?

슀마트 μŠ€ν† μ–΄μ—μ„œ ν™œμš©ν•˜λŠ” κΈ°λŠ₯을 μ œκ°€ κ΅¬ν˜„ν•΄λ³Έλ‹€λ©΄ μ–΄λ–»κ²Œ κ΅¬ν˜„ν•΄λ³Όμ§€ 상상해 λ΄€μŠ΅λ‹ˆλ‹€. API μš”μ²­μ„ μ²˜λ¦¬ν•˜λŠ” λ¦¬μ†ŒμŠ€ μ„œλ²„κ°€ 단일 μΈμŠ€ν„΄μŠ€μΈμ§€, ν΄λŸ¬μŠ€ν„°(λΆ„μ‚° ν™˜κ²½) 인지에 따라 호좜 ν—ˆμš©λŸ‰(Rate/Quota)을 κ΅¬ν˜„ν•˜λŠ” λ°©μ‹μ€ μžμ—°μŠ€λŸ½κ²Œ λ‹¬λΌμ§‘λ‹ˆλ‹€.

ν•˜μ§€λ§Œ 주된 핡심은 ν•˜λ‚˜μΈλ°μš”. λ°”λ‘œ “μš”μ²­μ΄ λ“€μ–΄μ˜¬ λ•Œλ§ˆλ‹€ ν—ˆμš©λŸ‰μ„ μ°¨κ°ν•˜λŠ” λ‘œμ§μ€ λ°˜λ“œμ‹œ μ›μžμ (atomic) 이어야 ν•œλ‹€.” μž…λ‹ˆλ‹€.

 

 

단일 μ„œλ²„μ—μ„œλŠ” JVM/λŸ°νƒ€μž„ λ©”λͺ¨λ¦¬ μ•ˆμ—μ„œ κ·Έ μ›μžμ„±μ„ ν™•λ³΄ν•˜λ©΄ 되고, λΆ„μ‚° ν™˜κ²½μ—μ„œλŠ” μ—¬λŸ¬ λ…Έλ“œκ°€ 동일 μƒνƒœλ₯Ό κ³΅μœ ν•΄μ•Ό ν•˜λ―€λ‘œ Redis 같은 쀑앙 μƒνƒœ μ €μž₯μ†Œμ™€ μ„œλ²„ μΈ‘ μ›μž μ‹€ν–‰(Lua)으둜 ꡬ성할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

1️⃣ 단일 μ„œλ²„ ν™˜κ²½

단일 μ„œλ²„ ν™˜κ²½μ—μ„œλŠ” “호좜 ν—ˆμš©λŸ‰ μƒνƒœ”κ°€ ν•œ ν”„λ‘œμ„ΈμŠ€ λ©”λͺ¨λ¦¬ μ•ˆμ—λ§Œ μ‘΄μž¬ν•˜λ©΄ λ©λ‹ˆλ‹€. 즉, μ „μ—­μ μœΌλ‘œ κ³΅μœ λ˜λŠ” μƒνƒœλŠ” 싱글톀 객체둜 두고, 토큰/μΉ΄μš΄ν„° μ‘°μž‘μ„ AtomicLong, AtomicInteger, ν˜Ήμ€ CAS μ•Œκ³ λ¦¬μ¦˜ 기반으둜 직접 κ΅¬ν˜„ν•˜λ©΄ λ™μ‹œμ„± 문제λ₯Ό ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

단일 μ„œλ²„μ΄κΈ΄ ν•˜μ§€λ§Œ μš”μ²­μ€ λ™μ‹œλ‘œ λ“€μ–΄μ˜΅λ‹ˆλ‹€. synchronized 같은 락도 κ°€λŠ₯ν•˜μ§€λ§Œ, QPSκ°€ λ†’μ•„μ§ˆμˆ˜λ‘ 경합이 μ»€μ§‘λ‹ˆλ‹€. ν† ν°μ˜ 수λ₯Ό λ³€ν™”μ‹œν‚€λŠ” 건 κ°€λ²Όμš΄ μž‘μ—…μ΄λ―€λ‘œ 토큰 버킷 μƒνƒœλ₯Ό ν•˜λ‚˜μ˜ ꡬ쑰둜 보고, 락을 κ±°λŠ” 것이 μ•„λ‹Œ CAS μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λ©΄ 맀우 κ°€λ³κ²Œ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

ν•˜μ§€λ§Œ 이런 방법은 μ„œλ²„κ°€ 2λŒ€λ‘œ λŠ˜μ–΄λ‚˜λŠ” μˆœκ°„, 각 μ„œλ²„κ°€ λ…λ¦½λœ 토큰을 κ°–κ²Œ λ˜μ–΄ “전체 ν—ˆμš©λŸ‰”을 컨트둀 ν•  수 μ—†κ²Œ λ©λ‹ˆλ‹€. λ˜ν•œ μ„œλ²„ μž¬μ‹œμž‘ μ‹œ μƒνƒœκ°€ μ΄ˆκΈ°ν™”λœλ‹€λŠ” 단점도 μžˆμŠ΅λ‹ˆλ‹€.
이런 방식은 λ¦¬μ†ŒμŠ€ μ„œλ²„κ°€ 단일 μΈμŠ€ν„΄μŠ€λΌλŠ” μ „μ œκ°€ μœ μ§€λ  λ•Œλ§Œ μ™„μ „ν•œ λ‹΅μž…λ‹ˆλ‹€.

 

 

2️⃣ λΆ„μ‚° ν™˜κ²½

λŸ¬ν”„ν•˜κ²Œ ν‘œν˜„ν•œ 이미지

 

λΆ„μ‚° ν™˜κ²½μ—μ„œλŠ” Redis + Lua둜 “μ „μ—­ μ›μžμ„±”을 λ§Œλ“€μ–΄ κ΅¬ν˜„ν•  수 μžˆμ„ 거라 μƒκ°λ©λ‹ˆλ‹€.

λ¦¬μ†ŒμŠ€ μ„œλ²„κ°€ μ—¬λŸ¬ λŒ€λ‘œ ν™•μž₯λ˜λŠ” μˆœκ°„, κ°€μž₯ λ¨Όμ € κΉ¨μ§€λŠ” 것이 “ν—ˆμš©λŸ‰ μƒνƒœμ˜ 일관성”μž…λ‹ˆλ‹€. μ„œλ²„ A와 μ„œλ²„ Bκ°€ λ™μ‹œμ— 토큰을 차감할 λ•Œ, λ‘˜μ΄ 같은 μƒνƒœκ°’μ„ 바라보지 μ•ŠμœΌλ©΄ 이런 μš”μ²­λŸ‰ μ œν•œμ΄ λ¬΄μ˜λ―Έν•΄μ§‘λ‹ˆλ‹€. κ·Έλž˜μ„œ λΆ„μ‚° ν™˜κ²½μ—μ„œλŠ” “μ „μ—­ μƒνƒœ”λ₯Ό ν•œ 곳에 λͺ¨μ•„μ•Ό ν•˜κ³ , κ·Έ μƒνƒœ 갱신은 경쟁 쑰건 없이 μ›μžμ μœΌλ‘œ 이뀄져야 ν•©λ‹ˆλ‹€.

 

μ—¬κΈ°μ„œ Redisκ°€ κ°•λ ₯ν•œ μ΄μœ λŠ” 두 κ°€μ§€μž…λ‹ˆλ‹€.

  1. 쀑앙 μƒνƒœ μ €μž₯μ†Œλ‘œμ„œμ˜ μ—­ν• : λͺ¨λ“  λ…Έλ“œκ°€ 같은 버킷 μƒνƒœλ₯Ό λ³Έλ‹€.
  2. μ„œλ²„ μΈ‘ μ›μž μ‹€ν–‰: Lua 슀크립트λ₯Ό Redis λ‚΄λΆ€μ—μ„œ μ‹€ν–‰ν•˜λ©΄, μŠ€ν¬λ¦½νŠΈκ°€ 끝날 λ•ŒκΉŒμ§€ λ‹€λ₯Έ λͺ…령이 끼어듀지 μ•Šμ•„ “토큰 κ°’ 확인 + 차감”을 ν•˜λ‚˜μ˜ νŠΈλžœμž­μ…˜μ²˜λŸΌ μ²˜λ¦¬ν•  수 μžˆλ‹€.

 

μ²˜μŒμ—λŠ” “뢄산락을 작고 토큰을 차감”을 λ– μ˜¬λ¦¬κΈ° μ‰½μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ λ§€ μš”μ²­λ§ˆλ‹€ 락을 μž‘λŠ” κ΅¬μ‘°λŠ” 락 κ²½ν•©κ³Ό λ„€νŠΈμ›Œν¬ μ™•λ³΅μœΌλ‘œ 인해 μ²˜λ¦¬λŸ‰μ΄ λ–¨μ–΄μ§€κΈ° μ‰½μŠ΅λ‹ˆλ‹€. 반면 Redis LuaλŠ”

  • 버킷 쑰회
  • refill 계산
  • 차감
  • μ €μž₯
  • κ²°κ³Ό λ°˜ν™˜

을 ν•œ 번의 호좜둜 μ²˜λ¦¬ν•  수 μžˆμ–΄, 락 없이도 λ™μ‹œμ„± λ¬Έμ œκ°€ μ‚¬λΌμ§‘λ‹ˆλ‹€.

 

 

λ˜ν•œ, λΆ„μ‚° ν™˜κ²½μ—μ„œ 초 κ²½κ³„λ§ˆλ‹€ μΉ΄μš΄ν„°λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 방식은 더 λΉ„νš¨μœ¨μ μ΄λΌ μƒκ°ν•©λ‹ˆλ‹€. μ—¬λŸ¬ μ„œλ²„/μŠ€μΌ€μ€„λŸ¬κ°€ κ°œμž…λ˜λ©΄μ„œ μ•½κ°„μ˜ 지연이 생기고, 경계 μ‹œμ μ— 였λ₯˜κ°€ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ Redisμ—μ„œλ„ 단일 μ„œλ²„μ™€ λ™μΌν•˜κ²Œ λ§ˆμ§€λ§‰ refill μ‹œκ°μ„ μ €μž₯ν•˜κ³  κ³„μ‚°μœΌλ‘œ μ±„μš°λŠ” 방법이 λ‚˜μ„ 것 κ°™μŠ΅λ‹ˆλ‹€.

 

 

ν‚€ μ„€κ³„λŠ” 계측 ꡬ쑰λ₯Ό λ°˜μ˜ν•˜λ©΄ λ©λ‹ˆλ‹€.

  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ Rate limit: rl:{app_id}:{api}
  • SELLER Quota limit: ql:{seller_token}:{api}

 

μŠ€λ§ˆνŠΈμŠ€ν† μ–΄μ²˜λŸΌ Rate와 Quotaκ°€ λ™μ‹œμ— μ‘΄μž¬ν•˜λ©΄, “λ‘˜ λ‹€ 톡과해야 ν—ˆμš©”이 κΈ°λ³Έ κ·œμΉ™μž…λ‹ˆλ‹€.
ν•˜λ‚˜μ˜ Lua μŠ€ν¬λ¦½νŠΈμ—μ„œ Rate/Quota 버킷을 λ™μ‹œμ— refill + μ²΄ν¬ν•˜κ³ , λ‘˜ λ‹€ 성곡일 λ•Œλ§Œ λ‘˜ λ‹€ 차감해야 ν•©λ‹ˆλ‹€.
μ΄λ ‡κ²Œ ν•˜λ©΄ λΆ„μ‚° ν™˜κ²½μ—μ„œλ„ μΌκ΄€μ„±μ΄ μœ μ§€λ©λ‹ˆλ‹€.

 

 

κ²°κ΅­ 단일 μ„œλ²„μ™€ λΆ„μ‚° ν™˜κ²½μ˜ μ°¨μ΄λŠ” μ›μžμ„±μ„ 보μž₯ν•˜λŠ” μ΅œμ„ μ˜ 방법에 따라 λ‹¬λΌμ§€κ²Œ λ©λ‹ˆλ‹€.

  • 단일 μ„œλ²„: μƒˆλ‘œμš΄ μ™ΈλΆ€ μ»΄ν¬λ„ŒνŠΈ(μΊμ‹œ/DB/Redis λ“±)을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  ν”„λ‘œμ„ΈμŠ€ λ©”λͺ¨λ¦¬ μ•ˆμ—μ„œ Atomic/CAS둜 ν•΄κ²°
  • λΆ„μ‚° ν™˜κ²½: 곡유 μ €μž₯μ†Œ(Redis)둜 μƒνƒœλ₯Ό λͺ¨μœΌκ³ , Lua 슀크립트둜 μ„œλ²„ μΈ‘ μ›μž μ‹€ν–‰

 

πŸ“œμ°Έκ³ 

https://github.com/commerce-api-naver/commerce-api/discussions/6

 

μ‚¬μš©λŸ‰ μ œν•œ λ˜λŠ” ν˜ΈμΆœλŸ‰ μ œν•œμ΄ μžˆλ‚˜μš”? · commerce-api-naver commerce-api · Discussion #6

Q. μ‚¬μš©λŸ‰ μ œν•œ λ˜λŠ” ν˜ΈμΆœλŸ‰ μ œν•œμ΄ μžˆλ‚˜μš”? A. API별 μ΄ˆλ‹Ή 호좜 횟수λ₯Ό μ‚°μ •ν•˜μ—¬ μ •ν•΄μ§„ 횟수 μ΄μƒμ˜ ν˜ΈμΆœμ„ μ œν•œν•©λ‹ˆλ‹€. Note이 κ²Œμ‹œκΈ€μ—μ„œλŠ” μŠ€λ§ˆνŠΈμŠ€ν† μ–΄ νŒλ§€μžκ°€ 컀머슀APIμ„Όν„°μ—μ„œ μžμ‹ μ΄ 운

github.com

https://github.com/commerce-api-naver/api-agency/discussions/12

 

[μ€‘μš”] '동적 호좜 ν—ˆμš©λŸ‰' μ „λ©΄ 적용 μ•ˆλ‚΄ · commerce-api-naver api-agency · Discussion #12

동적 호좜 ν—ˆμš©λŸ‰ μ „λ©΄ 적용 '동적 호좜 ν—ˆμš©λŸ‰'은 각 API별 호좜 ν—ˆμš©λŸ‰μ„ κ°€λ³€μ μœΌλ‘œ μ μš©ν•˜λŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€. 컀머슀API ν”Œλž«νΌ μ„œλΉ„μŠ€λ₯Ό κ΅¬μ„±ν•˜λŠ” μ—¬λŸ¬ μš”μ†Œλ“€μ„ κ³ λ €ν•œ 각 API별 호좜 ν—ˆμš©λŸ‰ 수

github.com

https://apicenter.commerce.naver.com/docs/restriction

 

μ œμ•½ 사항 | 컀머슀API

μ œμ•½ 사항 컀머슀API의 각 κΈ°λŠ₯별 μ„€λͺ… μ˜μ—­μ—μ„œλŠ” λ‹€μŒκ³Ό 같이 'μ œμ•½ 사항'에 λŒ€ν•΄μ„œ μ•ˆλ‚΄ν•©λ‹ˆλ‹€. μ›Ή μ„œλ²„ μΈμ¦μ„œ(TLS) 버전 μ œμ•½β€‹ 컀머슀APIλŠ” μ›Ή μ„œλ²„ μΈμ¦μ„œ(TLS) 버전 1.2 μ΄μƒμ—μ„œλ§Œ 정상 λ™μž‘

apicenter.commerce.naver.com

https://github.com/commerce-api-naver/api-agency/discussions/23

 

동적 호좜 ν—ˆμš©λŸ‰ μ „λ©΄ μ μš©μ— λ”°λ₯Έ λŒ€ν–‰μ‚¬ λŒ€μ‘ 사항 · commerce-api-naver api-agency · Discussion #23

Noteλ³Έ κ²Œμ‹œκΈ€μ—μ„œμ˜ λͺ¨λ“  λ‚΄μš©μ€ 사전에 동적 호좜 ν—ˆμš©λŸ‰ μ „λ©΄ 적용과 κ΄€λ ¨ν•œ 곡지사항 λ‚΄μš©μ„ μ΄ν•΄ν•œ 것을 κ°€μ •ν•˜μ—¬ μ„€λͺ…ν•©λ‹ˆλ‹€. 1. μ„œλΉ„μŠ€ ν˜Όμž‘μ— λ”°λ₯Έ HTTP 429 응닡 λŒ€μ‘ (4/1) 각 APIλ₯Ό μ²˜λ¦¬ν•˜

github.com

 

λŒ“κΈ€