最近有一个python实现代理池的项目,其中获取代理这个地方需要用到分布式锁,
具体逻辑就算请求进来之后先从redis中拿ip,如果redis中没有ip则去执行一个添加ip的操作,看上去这个操作没什么问题,但是并发高的时候会有很多请求都去执行这个操作,这个时候就需要用到分布式锁了,只有加锁成功的请求才去执行这个操作,其他请求可以等待或者先返回一个错误码,上代码

    # 加锁
    def acquire_lock(conn):
    	# 锁名称
        lock_name = "lock_name"
        # 加锁成功返回True
        if conn.setnx(lock_name, 1):
        	# 设置过期时间,3秒
            conn.expire(lock_name, 3)
            return True
        # 如果存在锁,且这个锁没有过期时间则为其设置过期时间,避免死锁
        elif conn.ttl(lock_name) == -1:
            conn.expire(lock_name, 3)
        return False

	#释放锁
    def release_lock(conn):
        lock_name = "loack_name"
        with conn.pipeline(True) as pipe:
       		# 循环执行,直到操作成功
            while True:
                try:
                    # 通过watch命令监视某个键,当该键未被其他客户端修改值时,事务成功执行。当事务运行过程中,发现该值被其他客户端更新了值,任务失败
                    pipe.watch(lock_name)
                    # multi执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC 命令被调用时, 所有队列中的命令才会被执行
                    pipe.multi()
                    # 检查客户端是否仍然持有该锁
                    if pipe.get(lock_name):
                        # 删除键,释放锁
                        pipe.delete(lock_name)
                        # execute命令负责触发并执行事务中的所有命令
                        pipe.execute()
                        return True
                    pipe.unwatch()
                    break
                except redis.exceptions.WatchError:
                    # 释放锁期间,有其他客户端改变了键值对,锁释放失败,进行循环
                    pass
            return False
Logo

更多推荐