Python์์ Circuit Breaker ํจํด์ ๊ตฌํํ์ฌ ๋ด๊ฒฐํจ์ฑ ๋ฐ ํ๋ ฅ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์. ์ฐ์์ ์ธ ์คํจ๋ฅผ ๋ฐฉ์งํ๊ณ ์์คํ ์์ ์ฑ์ ํฅ์์ํค์ธ์.
Python Circuit Breaker: ๋ด๊ฒฐํจ์ฑ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ถ
๋ถ์ฐ ์์คํ ๋ฐ ๋ง์ดํฌ๋ก์๋น์ค ํ๊ฒฝ์์ ์ค๋ฅ ์ฒ๋ฆฌ๋ ํผํ ์ ์์ต๋๋ค. ๋คํธ์ํฌ ๋ฌธ์ , ๊ณผ๋ถํ๋ ์๋ฒ ๋๋ ์๊ธฐ์น ์์ ๋ฒ๊ทธ๋ก ์ธํด ์๋น์ค๊ฐ ์ฌ์ฉ ๋ถ๊ฐ๋ฅํด์ง ์ ์์ต๋๋ค. ์คํจํ ์๋น์ค๋ฅผ ์ ๋๋ก ์ฒ๋ฆฌํ์ง ๋ชปํ๋ฉด ์ฐ์์ ์ธ ์คํจ๋ก ์ด์ด์ ธ ์ ์ฒด ์์คํ ์ด ๋ค์ด๋ ์ ์์ต๋๋ค. Circuit Breaker ํจํด์ ์ด๋ฌํ ์ฐ์์ ์ธ ์คํจ๋ฅผ ๋ฐฉ์งํ๊ณ ๋ณด๋ค ํ๋ ฅ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๊ฐ๋ ฅํ ๊ธฐ์ ์ ๋๋ค. ์ด ๊ธฐ์ฌ์์๋ Python์์ Circuit Breaker ํจํด์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
Circuit Breaker ํจํด์ด๋ ๋ฌด์์ ๋๊น?
์ ๊ธฐ ํ๋ก ์ฐจ๋จ๊ธฐ์์ ์๊ฐ์ ์ป์ Circuit Breaker ํจํด์ ์คํจํ ์ ์๋ ์์ ์ ๋ํ ํ๋ก์ ์ญํ ์ ํฉ๋๋ค. ์ด๋ฌํ ์์ ์ ์ฑ๊ณต ๋ฐ ์คํจ์จ์ ๋ชจ๋ํฐ๋งํ๊ณ ํน์ ์คํจ ์๊ณ๊ฐ์ ๋๋ฌํ๋ฉด ํ๋ก๋ฅผ "ํธ๋ฆฝ"์์ผ ์คํจํ ์๋น์ค์ ๋ํ ์ถ๊ฐ ํธ์ถ์ ๋ฐฉ์งํฉ๋๋ค. ์ด๋ฅผ ํตํด ์คํจํ ์๋น์ค๋ ์์ฒญ์ ์๋๋์ง ์๊ณ ๋ณต๊ตฌํ ์๊ฐ์ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ํธ์ถ ์๋น์ค๋ ๋ค์ด๋ ๊ฒ์ผ๋ก ์๋ ค์ง ์๋น์ค์ ์ฐ๊ฒฐํ๋ ค๊ณ ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
Circuit Breaker์๋ ์ธ ๊ฐ์ง ์ฃผ์ ์ํ๊ฐ ์์ต๋๋ค.
- Closed: Circuit Breaker๋ ์ ์ ์ํ์ด๋ฉฐ, ํธ์ถ์ด ๋ณดํธ๋ ์๋น์ค๋ฅผ ํต๊ณผํ๋๋ก ํ์ฉํฉ๋๋ค. ์ด๋ฌํ ํธ์ถ์ ์ฑ๊ณต ๋ฐ ์คํจ๋ฅผ ๋ชจ๋ํฐ๋งํฉ๋๋ค.
- Open: Circuit Breaker๊ฐ ํธ๋ฆฝ๋์ด ๋ณดํธ๋ ์๋น์ค์ ๋ํ ๋ชจ๋ ํธ์ถ์ด ์ฐจ๋จ๋ฉ๋๋ค. ์ง์ ๋ ์๊ฐ ์ด๊ณผ ๊ธฐ๊ฐ ํ Circuit Breaker๋ Half-Open ์ํ๋ก ์ ํ๋ฉ๋๋ค.
- Half-Open: Circuit Breaker๋ ์ ํ๋ ์์ ํ ์คํธ ํธ์ถ์ ๋ณดํธ๋ ์๋น์ค์ ํ์ฉํฉ๋๋ค. ์ด๋ฌํ ํธ์ถ์ด ์ฑ๊ณตํ๋ฉด Circuit Breaker๋ Closed ์ํ๋ก ๋์๊ฐ๋๋ค. ์คํจํ๋ฉด Open ์ํ๋ก ๋์๊ฐ๋๋ค.
๋ค์์ ๊ฐ๋จํ ๋น์ ์ ๋๋ค. ATM์์ ๋์ ์ธ์ถํ๋ ค๊ณ ํ๋ค๊ณ ์์ํด ๋ณด์ธ์. ATM์ด ๋ฐ๋ณต์ ์ผ๋ก ํ๊ธ์ ์ง๊ธํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ(์: ์ํ ์์คํ ์ค๋ฅ๋ก ์ธํด) Circuit Breaker๊ฐ ๊ฐ์ ํฉ๋๋ค. ์คํจํ ๊ฐ๋ฅ์ฑ์ด ๋์ ์ธ์ถ ์๋๋ฅผ ๊ณ์ํ๋ ๋์ Circuit Breaker๋ ์ผ์์ ์ผ๋ก ์ถ๊ฐ ์๋๋ฅผ ์ฐจ๋จํฉ๋๋ค(Open ์ํ). ์ ์ ํ ๋จ์ผ ์ธ์ถ ์๋๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค(Half-Open ์ํ). ํด๋น ์๋๊ฐ ์ฑ๊ณตํ๋ฉด Circuit Breaker๋ ์ ์ ์๋์ ์ฌ๊ฐํฉ๋๋ค(Closed ์ํ). ์คํจํ๋ฉด Circuit Breaker๋ ๋ ๊ธด ๊ธฐ๊ฐ ๋์ Open ์ํ๋ฅผ ์ ์งํฉ๋๋ค.
Circuit Breaker๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
Circuit Breaker๋ฅผ ๊ตฌํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ๊ฐ์ง ์ด์ ์ด ์์ต๋๋ค.
- ์ฐ์์ ์ธ ์คํจ ๋ฐฉ์ง: ์คํจํ ์๋น์ค์ ๋ํ ํธ์ถ์ ์ฐจ๋จํจ์ผ๋ก์จ Circuit Breaker๋ ์์คํ ์ ๋ค๋ฅธ ๋ถ๋ถ์ผ๋ก ์คํจ๊ฐ ํ์ฐ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
- ์์คํ ๋ณต์๋ ฅ ํฅ์: Circuit Breaker๋ ์คํจํ ์๋น์ค๊ฐ ์์ฒญ์ ์๋๋์ง ์๊ณ ๋ณต๊ตฌํ ์๊ฐ์ ํ์ฉํ์ฌ ๋ณด๋ค ์์ ์ ์ด๊ณ ํ๋ ฅ์ ์ธ ์์คํ ์ ๋ง๋ญ๋๋ค.
- ๋ฆฌ์์ค ์๋น ๊ฐ์: ์คํจํ ์๋น์ค์ ๋ํ ๋ถํ์ํ ํธ์ถ์ ํผํจ์ผ๋ก์จ Circuit Breaker๋ ํธ์ถ ์๋น์ค์ ํธ์ถ๋๋ ์๋น์ค ๋ชจ๋์์ ๋ฆฌ์์ค ์๋น๋ฅผ ์ค์ ๋๋ค.
- ๋์ฒด ๋ฉ์ปค๋์ฆ ์ ๊ณต: ํ๋ก๊ฐ ์ด๋ ค ์์ผ๋ฉด ํธ์ถ ์๋น์ค๋ ์บ์๋ ๊ฐ์ ๋ฐํํ๊ฑฐ๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๋ฑ์ ๋์ฒด ๋ฉ์ปค๋์ฆ์ ์คํํ์ฌ ๋ ๋์ ์ฌ์ฉ์ ํ๊ฒฝ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
Python์์ Circuit Breaker ๊ตฌํ
Python์์ Circuit Breaker ํจํด์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ต๋๋ค. ์ฒ์๋ถํฐ ์ง์ ๊ตฌํํ๊ฑฐ๋ ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ๋ ๊ฐ์ง ์ ๊ทผ ๋ฐฉ์์ ๋ชจ๋ ์ดํด๋ด ๋๋ค.
1. ์ฌ์ฉ์ ์ ์ Circuit Breaker ๊ตฌ์ถ
ํต์ฌ ๊ฐ๋ ์ ์ดํดํ๊ธฐ ์ํด ๊ธฐ๋ณธ ์ฌ์ฉ์ ์ ์ ๊ตฌํ๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค. ์ด ์์ ์์๋ ์ค๋ ๋ ์์ ์ฑ์ ์ํด `threading` ๋ชจ๋์ ์ฌ์ฉํ๊ณ ์๊ฐ ์ด๊ณผ ์ฒ๋ฆฌ๋ฅผ ์ํด `time` ๋ชจ๋์ ์ฌ์ฉํฉ๋๋ค.
import time
import threading
class CircuitBreaker:
def __init__(self, failure_threshold, recovery_timeout):
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.state = "CLOSED"
self.failure_count = 0
self.last_failure_time = None
self.lock = threading.Lock()
def call(self, func, *args, **kwargs):
with self.lock:
if self.state == "OPEN":
if time.time() - self.last_failure_time > self.recovery_timeout:
self.state = "HALF_OPEN"
else:
raise CircuitBreakerError("Circuit breaker is open")
try:
result = func(*args, **kwargs)
self.reset()
return result
except Exception as e:
self.record_failure()
raise e
def record_failure(self):
with self.lock:
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.failure_threshold:
self.state = "OPEN"
print("Circuit breaker opened")
def reset(self):
with self.lock:
self.failure_count = 0
self.state = "CLOSED"
print("Circuit breaker closed")
class CircuitBreakerError(Exception):
pass
# Example Usage
def unreliable_service():
# Simulate a service that sometimes fails
import random
if random.random() < 0.5:
raise Exception("Service failed")
else:
return "Service successful"
circuit_breaker = CircuitBreaker(failure_threshold=3, recovery_timeout=10)
for i in range(10):
try:
result = circuit_breaker.call(unreliable_service)
print(f"Call {i+1}: {result}")
except CircuitBreakerError as e:
print(f"Call {i+1}: {e}")
except Exception as e:
print(f"Call {i+1}: Service failed: {e}")
time.sleep(1)
์ค๋ช :
- `CircuitBreaker` ํด๋์ค:
- `__init__(self, failure_threshold, recovery_timeout)`: ์คํจ ์๊ณ๊ฐ(ํ๋ก๋ฅผ ํธ๋ฆฝํ๊ธฐ ์ ์ ์คํจ ํ์), ๋ณต๊ตฌ ์๊ฐ ์ด๊ณผ(Half-Open ์ํ๋ฅผ ์๋ํ๊ธฐ ์ ์ ๋๊ธฐํ๋ ์๊ฐ)๋ก Circuit Breaker๋ฅผ ์ด๊ธฐํํ๊ณ ์ด๊ธฐ ์ํ๋ฅผ `CLOSED`๋ก ์ค์ ํฉ๋๋ค.
- `call(self, func, *args, **kwargs)`: ๋ณดํธํ๋ ค๋ ํจ์๋ฅผ ๋ํํ๋ ์ฃผ์ ๋ฉ์๋์ ๋๋ค. Circuit Breaker์ ํ์ฌ ์ํ๋ฅผ ํ์ธํฉ๋๋ค. `OPEN`์ธ ๊ฒฝ์ฐ ๋ณต๊ตฌ ์๊ฐ ์ด๊ณผ๊ฐ ๊ฒฝ๊ณผํ๋์ง ํ์ธํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด `HALF_OPEN`์ผ๋ก ์ ํ๋ฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด `CircuitBreakerError`๋ฅผ ๋ฐ์์ํต๋๋ค. ์ํ๊ฐ `OPEN`์ด ์๋๋ฉด ํจ์๋ฅผ ์คํํ๊ณ ์ ์ฌ์ ์ธ ์์ธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- `record_failure(self)`: ์คํจ ํ์๋ฅผ ๋๋ฆฌ๊ณ ์คํจ ์๊ฐ์ ๊ธฐ๋กํฉ๋๋ค. ์คํจ ํ์๊ฐ ์๊ณ๊ฐ์ ์ด๊ณผํ๋ฉด ํ๋ก๋ฅผ `OPEN` ์ํ๋ก ์ ํํฉ๋๋ค.
- `reset(self)`: ์คํจ ํ์๋ฅผ ์ฌ์ค์ ํ๊ณ ํ๋ก๋ฅผ `CLOSED` ์ํ๋ก ์ ํํฉ๋๋ค.
- `CircuitBreakerError` ํด๋์ค: Circuit Breaker๊ฐ ์ด๋ ค ์์ ๋ ๋ฐ์ํ๋ ์ฌ์ฉ์ ์ ์ ์์ธ์ ๋๋ค.
- `unreliable_service()` ํจ์: ๋ฌด์์๋ก ์คํจํ๋ ์๋น์ค๋ฅผ ์๋ฎฌ๋ ์ด์ ํฉ๋๋ค.
- ์ฌ์ฉ ์์ : `CircuitBreaker` ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ `unreliable_service()` ํจ์๋ฅผ ๋ณดํธํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
์ฌ์ฉ์ ์ ์ ๊ตฌํ์ ์ํ ์ฃผ์ ๊ณ ๋ ค ์ฌํญ:
- ์ค๋ ๋ ์์ ์ฑ: `threading.Lock()`์ ํนํ ๋์ ํ๊ฒฝ์์ ์ค๋ ๋ ์์ ์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ: `try...except` ๋ธ๋ก์ ๋ณดํธ๋ ์๋น์ค์์ ์์ธ๋ฅผ ํฌ์ฐฉํ๊ณ `record_failure()`๋ฅผ ํธ์ถํฉ๋๋ค.
- ์ํ ์ ํ: `CLOSED`, `OPEN` ๋ฐ `HALF_OPEN` ์ํ ๊ฐ์ ์ ํ ๋ ผ๋ฆฌ๋ `call()` ๋ฐ `record_failure()` ๋ฉ์๋ ๋ด์์ ๊ตฌํ๋ฉ๋๋ค.
2. ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ: `pybreaker`
์์ฒด Circuit Breaker๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ์ ์ข์ ํ์ต ๊ฒฝํ์ด ๋ ์ ์์ง๋ง, ์ ํ ์คํธ๋ ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํ๋ก๋์ ํ๊ฒฝ์์ ๋ ๋์ ์ ํ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. Circuit Breaker ํจํด์ ๊ตฌํํ๊ธฐ ์ํ ์ธ๊ธฐ ์๋ Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ํ๋๋ `pybreaker`์ ๋๋ค.
์ค์น:
pip install pybreaker
์ฌ์ฉ ์์ :
import pybreaker
import time
# Define a custom exception for our service
class ServiceError(Exception):
pass
# Simulate an unreliable service
def unreliable_service():
import random
if random.random() < 0.5:
raise ServiceError("Service failed")
else:
return "Service successful"
# Create a CircuitBreaker instance
circuit_breaker = pybreaker.CircuitBreaker(
fail_max=3, # Number of failures before opening the circuit
reset_timeout=10, # Time in seconds before attempting to close the circuit
name="MyService"
)
# Wrap the unreliable service with the CircuitBreaker
@circuit_breaker
def call_unreliable_service():
return unreliable_service()
# Make calls to the service
for i in range(10):
try:
result = call_unreliable_service()
print(f"Call {i+1}: {result}")
except pybreaker.CircuitBreakerError as e:
print(f"Call {i+1}: Circuit breaker is open: {e}")
except ServiceError as e:
print(f"Call {i+1}: Service failed: {e}")
time.sleep(1)
์ค๋ช :
- ์ค์น: `pip install pybreaker` ๋ช ๋ น์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํฉ๋๋ค.
- `pybreaker.CircuitBreaker` ํด๋์ค:
- `fail_max`: Circuit Breaker๊ฐ ์ด๋ฆฌ๊ธฐ ์ ์ ์ฐ์ ์คํจ ํ์๋ฅผ ์ง์ ํฉ๋๋ค.
- `reset_timeout`: Circuit Breaker๊ฐ Half-Open ์ํ๋ก ์ ํ๋๊ธฐ ์ ์ ์ด๋ ค ์๋ ์๊ฐ(์ด)์ ์ง์ ํฉ๋๋ค.
- `name`: Circuit Breaker์ ๋ํ ์ค๋ช ์ ์ธ ์ด๋ฆ์ ๋๋ค.
- ๋ฐ์ฝ๋ ์ดํฐ: `@circuit_breaker` ๋ฐ์ฝ๋ ์ดํฐ๋ `unreliable_service()` ํจ์๋ฅผ ๋ํํ์ฌ Circuit Breaker ๋ ผ๋ฆฌ๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- ์์ธ ์ฒ๋ฆฌ: `try...except` ๋ธ๋ก์ ํ๋ก๊ฐ ์ด๋ ค ์์ ๋ `pybreaker.CircuitBreakerError`๋ฅผ ํฌ์ฐฉํ๊ณ ์๋น์ค๊ฐ ์คํจํ ๋ `ServiceError`(์ฌ์ฉ์ ์ ์ ์์ธ)๋ฅผ ํฌ์ฐฉํฉ๋๋ค.
`pybreaker` ์ฌ์ฉ์ ์ด์ :
- ๊ตฌํ ๋จ์ํ: `pybreaker`๋ ๊น๋ํ๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ด API๋ฅผ ์ ๊ณตํ์ฌ ์์ฉ๊ตฌ ์ฝ๋๋ฅผ ์ค์ ๋๋ค.
- ์ค๋ ๋ ์์ ์ฑ: `pybreaker`๋ ์ค๋ ๋ ์์ ํ๋ฏ๋ก ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํฉ๋๋ค.
- ์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅ: ์คํจ ์๊ณ๊ฐ, ์ฌ์ค์ ์๊ฐ ์ด๊ณผ ๋ฐ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ๊ฐ์ ๋ค์ํ ๋งค๊ฐ๋ณ์๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
- ์ด๋ฒคํธ ๋ฆฌ์ค๋: `pybreaker`๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ง์ํ๋ฏ๋ก Circuit Breaker์ ์ํ๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์กฐ์น๋ฅผ ์ทจํ ์ ์์ต๋๋ค(์: ๋ก๊น , ๊ฒฝ๊ณ ๋ณด๋ด๊ธฐ).
3. ๊ณ ๊ธ Circuit Breaker ๊ฐ๋
๊ธฐ๋ณธ ๊ตฌํ ์ธ์๋ Circuit Breaker๋ฅผ ์ฌ์ฉํ ๋ ๊ณ ๋ คํด์ผ ํ ๋ช ๊ฐ์ง ๊ณ ๊ธ ๊ฐ๋ ์ด ์์ต๋๋ค.
- ๋ฉํธ๋ฆญ ๋ฐ ๋ชจ๋ํฐ๋ง: Circuit Breaker์ ๋์์ ์ดํดํ๊ณ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์๋ณํ๋ ค๋ฉด ์ฑ๋ฅ์ ๋ํ ๋ฉํธ๋ฆญ์ ์์งํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. Prometheus ๋ฐ Grafana์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ๋ฉํธ๋ฆญ์ ์๊ฐํํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๋ฉํธ๋ฆญ์ ์ถ์ ํฉ๋๋ค.
- Circuit Breaker ์ํ(Open, Closed, Half-Open)
- ์ฑ๊ณตํ ํธ์ถ ํ์
- ์คํจํ ํธ์ถ ํ์
- ํธ์ถ ๋๊ธฐ ์๊ฐ
- ๋์ฒด ๋ฉ์ปค๋์ฆ: ํ๋ก๊ฐ ์ด๋ ค ์์ ๋ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ ๋ต์ด ํ์ํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ๋์ฒด ๋ฉ์ปค๋์ฆ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์บ์๋ ๊ฐ ๋ฐํ
- ์ฌ์ฉ์์๊ฒ ์ค๋ฅ ๋ฉ์์ง ํ์
- ๋์ฒด ์๋น์ค ํธ์ถ
- ๊ธฐ๋ณธ๊ฐ ๋ฐํ
- ๋น๋๊ธฐ Circuit Breaker: ๋น๋๊ธฐ ์ ํ๋ฆฌ์ผ์ด์ (`asyncio` ์ฌ์ฉ)์์๋ ๋น๋๊ธฐ Circuit Breaker ๊ตฌํ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ผ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋น๋๊ธฐ ์ง์์ ์ ๊ณตํฉ๋๋ค.
- ๋ฒํฌํค๋: ๋ฒํฌํค๋ ํจํด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ผ๋ถ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ํ ๋ถ๋ถ์ ์ค๋ฅ๊ฐ ๋ค๋ฅธ ๋ถ๋ถ์ผ๋ก ํ์ฐ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. Circuit Breaker๋ ๋ฒํฌํค๋์ ํจ๊ป ์ฌ์ฉํ์ฌ ํจ์ฌ ๋ ๊ฐ๋ ฅํ ๋ด๊ฒฐํจ์ฑ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
- ์๊ฐ ๊ธฐ๋ฐ Circuit Breaker: ์คํจ ํ์๋ฅผ ์ถ์ ํ๋ ๋์ ์๊ฐ ๊ธฐ๋ฐ Circuit Breaker๋ ๋ณดํธ๋ ์๋น์ค์ ํ๊ท ์๋ต ์๊ฐ์ด ์ฃผ์ด์ง ์๊ฐ ์ฐฝ ๋ด์์ ํน์ ์๊ณ๊ฐ์ ์ด๊ณผํ๋ ๊ฒฝ์ฐ ํ๋ก๋ฅผ ์ฝ๋๋ค.
์ค์ ์์ ๋ฐ ์ฌ์ฉ ์ฌ๋ก
๋ค์์ ๋ค์ํ ์๋๋ฆฌ์ค์์ Circuit Breaker๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ช ๊ฐ์ง ์ค์ ์์ ๋๋ค.
- ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ: ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ์์ ์๋น์ค๋ ์๋ก ์์กดํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. Circuit Breaker๋ ๋ค์ด์คํธ๋ฆผ ์๋น์ค์ ์ค๋ฅ๋ก ์ธํด ์๋น์ค๊ฐ ์๋๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ ์ ์๊ฑฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์๋ ์ ํ ์นดํ๋ก๊ทธ, ์ฃผ๋ฌธ ์ฒ๋ฆฌ ๋ฐ ๊ฒฐ์ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ณ๋์ ๋ง์ดํฌ๋ก์๋น์ค๊ฐ ์์ ์ ์์ต๋๋ค. ๊ฒฐ์ ์ฒ๋ฆฌ ์๋น์ค๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ฉด ์ฃผ๋ฌธ ์ฒ๋ฆฌ ์๋น์ค์ Circuit Breaker๋ ์ ์ฃผ๋ฌธ์ด ์์ฑ๋์ง ์๋๋ก ํ์ฌ ์ฐ์์ ์ธ ์คํจ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ฃผ ์ฐ๊ฒฐํ๋ ๊ฒฝ์ฐ Circuit Breaker๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ ์ ์์ ๋ ์ฐ๊ฒฐ ํญํ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์ง๋ฆฌ์ ์ผ๋ก ๋ถ์ฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ณ ๋ คํด ๋ณด์ญ์์ค. ๋คํธ์ํฌ ์ค๋จ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ญ ์ค ํ๋์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒฝ์ฐ Circuit Breaker๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฌ์ฉํ ์ ์๋ ์์ญ์ ๋ฐ๋ณต์ ์ผ๋ก ์ฐ๊ฒฐ์ ์๋ํ๋ ๊ฒ์ ๋ฐฉ์งํ์ฌ ์ฑ๋ฅ๊ณผ ์์ ์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
- ์ธ๋ถ API: ์ธ๋ถ API๋ฅผ ํธ์ถํ ๋ Circuit Breaker๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ผ์์ ์ธ ์ค๋ฅ ๋ฐ ์ค๋จ์ผ๋ก๋ถํฐ ๋ณดํธํ ์ ์์ต๋๋ค. ๋ง์ ์กฐ์ง์์ ๋ค์ํ ๊ธฐ๋ฅ์ ์ํด ํ์ฌ API์ ์์กดํฉ๋๋ค. API ํธ์ถ์ Circuit Breaker๋ก ๋ํํจ์ผ๋ก์จ ์กฐ์ง์ ๋ณด๋ค ๊ฐ๋ ฅํ ํตํฉ์ ๊ตฌ์ถํ๊ณ ์ธ๋ถ API ์ค๋ฅ์ ์ํฅ์ ์ค์ผ ์ ์์ต๋๋ค.
- ์ฌ์๋ ๋ ผ๋ฆฌ: Circuit Breaker๋ ์ฌ์๋ ๋ ผ๋ฆฌ์ ํจ๊ป ์๋ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฌธ์ ๋ฅผ ์ ํ์ํฌ ์ ์๋ ๊ณต๊ฒฉ์ ์ธ ์ฌ์๋๋ฅผ ํผํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Circuit Breaker๋ ์๋น์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ผ๋ก ์๋ ค์ง ๊ฒฝ์ฐ ์ฌ์๋๋ฅผ ๋ฐฉ์งํด์ผ ํฉ๋๋ค.
๊ธ๋ก๋ฒ ๊ณ ๋ ค ์ฌํญ
๊ธ๋ก๋ฒ ์ปจํ ์คํธ์์ Circuit Breaker๋ฅผ ๊ตฌํํ ๋๋ ๋ค์ ์ฌํญ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ๋คํธ์ํฌ ๋๊ธฐ ์๊ฐ: ๋คํธ์ํฌ ๋๊ธฐ ์๊ฐ์ ํธ์ถ ์๋น์ค์ ํธ์ถ๋๋ ์๋น์ค์ ์ง๋ฆฌ์ ์์น์ ๋ฐ๋ผ ํฌ๊ฒ ๋ค๋ฅผ ์ ์์ต๋๋ค. ๊ทธ์ ๋ฐ๋ผ ๋ณต๊ตฌ ์๊ฐ ์ด๊ณผ๋ฅผ ์กฐ์ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ถ๋ฏธ์ ์ ๋ฝ์ ์๋น์ค ๊ฐ์ ํธ์ถ์ ๋์ผํ ์ง์ญ ๋ด์ ํธ์ถ๋ณด๋ค ๋๊ธฐ ์๊ฐ์ด ๋ ๊ธธ ์ ์์ต๋๋ค.
- ์๊ฐ๋: ๋ชจ๋ ํ์์คํฌํ๊ฐ ๋ค๋ฅธ ์๊ฐ๋์์ ์ผ๊ด๋๊ฒ ์ฒ๋ฆฌ๋๋๋ก ํฉ๋๋ค. ํ์์คํฌํ ์ ์ฅ์๋ UTC๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ์ง์ญ์ ์ค๋จ: ์ง์ญ์ ์ค๋จ์ ๊ฐ๋ฅ์ฑ์ ๊ณ ๋ คํ๊ณ ํน์ ์ง์ญ์ผ๋ก ์ค๋ฅ๋ฅผ ๊ฒฉ๋ฆฌํ๊ธฐ ์ํด Circuit Breaker๋ฅผ ๊ตฌํํฉ๋๋ค.
- ๋ฌธํ์ ๊ณ ๋ ค ์ฌํญ: ๋์ฒด ๋ฉ์ปค๋์ฆ์ ์ค๊ณํ ๋ ์ฌ์ฉ์์ ๋ฌธํ์ ๋งฅ๋ฝ์ ๊ณ ๋ คํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ค๋ฅ ๋ฉ์์ง๋ ํ์งํ๋๊ณ ๋ฌธํ์ ์ผ๋ก ์ ์ ํด์ผ ํฉ๋๋ค.
๋ชจ๋ฒ ์ฌ๋ก
๋ค์์ Circuit Breaker๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ฐ ๋ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก์ ๋๋ค.
- ๋ณด์์ ์ธ ์ค์ ์ผ๋ก ์์: ๋น๊ต์ ๋ฎ์ ์คํจ ์๊ณ๊ฐ๊ณผ ๋ ๊ธด ๋ณต๊ตฌ ์๊ฐ ์ด๊ณผ๋ก ์์ํฉ๋๋ค. Circuit Breaker์ ๋์์ ๋ชจ๋ํฐ๋งํ๊ณ ํ์์ ๋ฐ๋ผ ์ค์ ์ ์กฐ์ ํฉ๋๋ค.
- ์ ์ ํ ๋์ฒด ๋ฉ์ปค๋์ฆ ์ฌ์ฉ: ์ข์ ์ฌ์ฉ์ ํ๊ฒฝ์ ์ ๊ณตํ๊ณ ์ค๋ฅ์ ์ํฅ์ ์ต์ํํ๋ ๋์ฒด ๋ฉ์ปค๋์ฆ์ ์ ํํฉ๋๋ค.
- Circuit Breaker ์ํ ๋ชจ๋ํฐ๋ง: Circuit Breaker์ ์ํ๋ฅผ ์ถ์ ํ๊ณ ํ๋ก๊ฐ ์ด๋ ค ์์ ๋ ์๋ฆผ์ ๋ณด๋ด๋๋ก ๊ฒฝ๊ณ ๋ฅผ ์ค์ ํฉ๋๋ค.
- Circuit Breaker ๋์ ํ ์คํธ: ํ ์คํธ ํ๊ฒฝ์์ ์ค๋ฅ๋ฅผ ์๋ฎฌ๋ ์ด์ ํ์ฌ Circuit Breaker๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํฉ๋๋ค.
- Circuit Breaker์ ๋ํ ๊ณผ๋ํ ์์กด ๋ฐฉ์ง: Circuit Breaker๋ ์ค๋ฅ๋ฅผ ์ํํ๊ธฐ ์ํ ๋๊ตฌ์ด์ง๋ง ์ด๋ฌํ ์ค๋ฅ์ ๊ทผ๋ณธ ์์ธ์ ํด๊ฒฐํ๋ ๋ฐ ๋ํ ๋์์ ์๋๋๋ค. ์๋น์ค ๋ถ์์ ์ ๊ทผ๋ณธ ์์ธ์ ์กฐ์ฌํ๊ณ ์์ ํฉ๋๋ค.
- ๋ถ์ฐ ์ถ์ ๊ณ ๋ ค: ์ฌ๋ฌ ์๋น์ค์์ ์์ฒญ์ ์ถ์ ํ๊ธฐ ์ํด ๋ถ์ฐ ์ถ์ ๋๊ตฌ(์: Jaeger ๋๋ Zipkin)๋ฅผ ํตํฉํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ค๋ฅ์ ๊ทผ๋ณธ ์์ธ์ ์๋ณํ๊ณ ์ ์ฒด ์์คํ ์ ๋ํ Circuit Breaker์ ์ํฅ์ ์ดํดํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
Circuit Breaker ํจํด์ ๋ด๊ฒฐํจ์ฑ ๋ฐ ํ๋ ฅ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ์ ์ฉํ ๋๊ตฌ์ ๋๋ค. Circuit Breaker๋ ์ฐ์์ ์ธ ์คํจ๋ฅผ ๋ฐฉ์งํ๊ณ ์คํจํ ์๋น์ค๊ฐ ๋ณต๊ตฌํ ์๊ฐ์ ํ์ฉํจ์ผ๋ก์จ ์์คํ ์์ ์ฑ๊ณผ ๊ฐ์ฉ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์์ฒด ๊ตฌํ์ ๊ตฌ์ถํ๋ `pybreaker`์ ๊ฐ์ ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ์ค๋๋ ์ ๋ณต์กํ ๋ถ์ฐ ํ๊ฒฝ์์ ๊ฐ๋ ฅํ๊ณ ์์ ์ ์ธ ์ํํธ์จ์ด๋ฅผ ๊ฐ๋ฐํ๋ ค๋ฉด Circuit Breaker ํจํด์ ํต์ฌ ๊ฐ๋ ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค.
์ด ๊ฐ์ด๋์ ์ค๋ช ๋ ์์น์ ๊ตฌํํ๋ฉด ๊ธ๋ก๋ฒ ๋ฒ์์ ๊ด๊ณ์์ด ์ค๋ฅ์ ๋ ํ๋ ฅ์ ์ธ Python ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ์ฌ ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ๋ ์์ ์ ์ธ ์์คํ ์ ๋ณด์ฅํ ์ ์์ต๋๋ค.