58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
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
|