本文目录导读:

- 使用pybreaker库(最常用)
- 配置高级选项
- 结合缓存实现降级
- 使用aiobreaker(异步版本)
- 使用hystrix-py(Netflix Hystrix风格)
- 结合重试机制的完整方案
- 监控和日志
- 配置建议
在Python数据处理和API调用的场景中,“熔断”通常指断路器模式(Circuit Breaker Pattern),用于防止系统雪崩,这里提供几种常见的Python数据API熔断配置方法:
使用pybreaker库(最常用)
from pybreaker import CircuitBreaker
import requests
import time
# 配置熔断器
breaker = CircuitBreaker(
fail_max=5, # 失败5次后断开
reset_timeout=60, # 60秒后尝试半开
state_storage=..., # 可选:存储状态,支持redis等
)
# 使用装饰器
@breaker
def call_api():
response = requests.get("https://api.example.com/data")
response.raise_for_status()
return response.json()
# 或手动调用
def call_api_with_breaker():
try:
with breaker:
response = requests.get("https://api.example.com/data")
response.raise_for_status()
return response.json()
except CircuitBreakerException:
return {"error": "Service unavailable, circuit is open"}
配置高级选项
from pybreaker import CircuitBreaker, CircuitBreakerError
import logging
# 更详细的配置
breaker = CircuitBreaker(
fail_max=10, # 最大失败次数
reset_timeout=30, # 重置超时(秒)
exclude_exceptions=[ # 不触发熔断的异常
requests.exceptions.HTTPError,
],
fallback_function=lambda: "Fallback response", # 降级函数
state_storage=..., # 状态存储(默认内存)
listeners=[logging_listener] # 事件监听器
)
# 自定义异常处理
class CustomCircuitBreaker(CircuitBreaker):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def call(self, func, *args, **kwargs):
try:
return super().call(func, *args, **kwargs)
except CircuitBreakerError:
return self._fallback_response
结合缓存实现降级
import redis
from pybreaker import CircuitBreaker
import functools
cache = redis.Redis()
breaker = CircuitBreaker(
fail_max=3,
reset_timeout=30,
listeners=[CacheFillingListener()]
)
@breaker
@functools.lru_cache(maxsize=128)
def get_api_data(api_key, params):
# 实际API调用
response = requests.get(
f"https://api.example.com/data",
params=params,
headers={"Authorization": f"Bearer {api_key}"}
)
return response.json()
# 带缓存的降级策略
def get_data_with_fallback(api_key, params):
try:
return get_api_data(api_key, params)
except CircuitBreakerError:
# 从缓存获取
cached = cache.get(f"api_cache:{params}")
if cached:
return json.loads(cached)
return {"error": "Service unavailable"}
使用aiobreaker(异步版本)
from aiobreaker import CircuitBreaker
import aiohttp
import asyncio
breaker = CircuitBreaker(
fail_max=5,
reset_timeout=60,
)
@breaker
async def call_api_async(session, url):
async with session.get(url) as response:
response.raise_for_status()
return await response.json()
async def main():
async with aiohttp.ClientSession() as session:
try:
data = await call_api_async(session,
"https://api.example.com/data")
except CircuitBreakerError:
print("Circuit is open, using fallback")
使用hystrix-py(Netflix Hystrix风格)
from hystrix import Command
import requests
class DataApiCommand(Command):
def __init__(self, url, params):
super().__init__(
command_key="DataApi",
group_key="ExternalAPI",
circuit_breaker_enabled=True,
circuit_breaker_request_volume_threshold=20,
circuit_breaker_sleep_window_in_milliseconds=5000,
circuit_breaker_error_threshold_percentage=50
)
self.url = url
self.params = params
def run(self):
response = requests.get(self.url, params=self.params)
response.raise_for_status()
return response.json()
def get_fallback(self):
return {"status": "fallback", "data": None}
# 使用
command = DataApiCommand("https://api.example.com/data", {"limit": 10})
result = command.execute()
结合重试机制的完整方案
import backoff
from pybreaker import CircuitBreaker, CircuitBreakerError
import requests
breaker = CircuitBreaker(fail_max=5, reset_timeout=60)
@backoff.on_exception(
backoff.expo, # 指数退避
requests.exceptions.RequestException, # 触发重试的异常
max_tries=3, # 最大重试次数
base=1, # 初始等待1秒
factor=2 # 每次翻倍
)
@breaker
def resilient_api_call():
response = requests.get("https://api.example.com/data")
response.raise_for_status()
return response.json()
# 使用
try:
data = resilient_api_call()
except CircuitBreakerError:
print("Circuit breaker open, skipping request")
except Exception as e:
print(f"API call failed after retries: {e}")
监控和日志
from pybreaker import CircuitBreakerListener
import logging
class LoggingListener(CircuitBreakerListener):
def state_change(self, cb, old_state, new_state):
logging.info(
f"Circuit breaker {cb.name}: {old_state} -> {new_state}"
)
def failure(self, cb, exc):
logging.warning(
f"Circuit breaker {cb.name} failure: {exc}"
)
def success(self, cb):
logging.debug(f"Circuit breaker {cb.name} success")
breaker = CircuitBreaker(
fail_max=5,
reset_timeout=60,
listeners=[LoggingListener()]
)
配置建议
- 失败阈值:根据API的SLA设置,一般3-10次
- 重置超时:通常30秒到5分钟,取决于恢复时间
- 异常排除:区分可恢复错误(如500)和不可恢复错误(如400)
- 降级策略:缓存、默认值、备用服务等
- 监控集成:Prometheus、Grafana等
选择哪种方案取决于你的具体需求:
- pybreaker:简单易用,适合大部分场景
- hystrix-py:需要Netflix Hystrix风格的复杂监控
- aiobreaker:异步框架(FastAPI等)
- 自定义:特殊业务逻辑需求