Flask缓存:Redis服务宕机时如何捕获异常并跳过缓存
Handling Redis Outages Gracefully in Flask-Cached Views
Great question! When your Redis instance goes down, Flask-Caching's @app.cache.memoize() decorator will throw a redis.exceptions.ConnectionError because it can't reach the cache server. To handle this gracefully and fall back to generating responses without caching, here are two solid approaches:
Option 1: Handle Cache Logic Inside the View Function
This approach gives you full control over cache reads/writes, letting you skip caching entirely when Redis is unavailable.
from redis.exceptions import ConnectionError @app.route('/foo/<arg>') def foo_response(arg): # Attempt to fetch from cache first cache_key = f"view/foo_response/{arg}" try: cached_result = app.cache.get(cache_key) if cached_result is not None: return cached_result except ConnectionError: # Redis is down, skip cache retrieval pass # Generate the actual response result = 'Hello ' + arg # Attempt to save result to cache try: # Match the timeout you'd use with memoize (default is 300s) app.cache.set(cache_key, result, timeout=300) except ConnectionError: # Redis is down, skip cache storage pass return result
Option 2: Create a Fault-Tolerant Memoize Decorator
If you prefer to keep your view functions clean and retain the decorator pattern, wrap the original memoize decorator with error handling:
from functools import wraps from redis.exceptions import ConnectionError def fault_tolerant_memoize(timeout=None): def decorator(func): # Get the original memoized function from Flask-Caching memoized_func = app.cache.memoize(timeout=timeout)(func) @wraps(func) def wrapper(*args, **kwargs): try: # Try to use the cached version first return memoized_func(*args, **kwargs) except ConnectionError: # Fall back to executing the original function directly return func(*args, **kwargs) return wrapper return decorator # Use the custom decorator instead of the default memoize @app.route('/foo/<arg>') @fault_tolerant_memoize() def foo_response(arg): return 'Hello ' + arg
Key Notes:
- Precise Exception Catching: We explicitly catch
redis.exceptions.ConnectionErrorinstead of a broadExceptionto avoid masking other unexpected errors in your code. - Timeout Consistency: If you use a custom timeout with
memoize, make sure to match it in thesetcall in Option 1. - Fallback Behavior: Both approaches ensure that even when Redis is down, your endpoint still returns the correct response instead of throwing a server error.
内容的提问来源于stack exchange,提问作者Camilo Gómez
相关产品推荐
相关产品推荐

