import uuid import logging from django.conf import settings from django.core.cache import cache logger = logging.getLogger(__name__) # Redis客户端(延迟初始化) _redis_client = None def _get_redis_client(): global _redis_client if _redis_client is None: import redis _redis_client = redis.Redis( host=settings.REDIS_HOST, port=settings.REDIS_PORT, password=settings.REDIS_PASSWORD, db=settings.REDIS_DB_CELERY, decode_responses=True, ) return _redis_client def acquire_lock(lock_key, timeout=10): """获取分布式锁,返回锁标识符,失败返回None""" client = _get_redis_client() identifier = str(uuid.uuid4()) result = client.set(lock_key, identifier, nx=True, ex=timeout) if result: logger.debug(f"获取锁成功: {lock_key}, 标识: {identifier}") return identifier return None def release_lock(lock_key, identifier): """释放分布式锁(仅当标识符匹配时才释放)""" if identifier is None: return False client = _get_redis_client() lua_script = """ if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end """ try: result = client.eval(lua_script, 1, lock_key, identifier) if result: logger.debug(f"释放锁成功: {lock_key}") else: logger.warning(f"释放锁失败(标识不匹配或锁已过期): {lock_key}") return bool(result) except Exception as e: logger.error(f"释放锁异常: {lock_key}, 错误: {e}") return False