版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dogpig945/article/details/78751664
所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁,通过create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。
#!/usr/bin/env python2.7
# -*- coding: utf8 -*-
"""
File: zklock.py
Brief: 分布式锁
Author:
Date:
"""
import logging, os, time
from kazoo.client import KazooClient
from kazoo.recipe.lock import Lock
class ZKDistributedLock():
def __init__(self, hosts, name, logger=None, timeout=1):
"""
:param hosts: zookeeper主机地址
:param name: 分布式锁名称
:param logger: 日志对象
:param timeout: 连接超时
"""
self._client = None
self._lock = None
# 创建客户端对象并初始化连接
try:
self._client = KazooClient(hosts=hosts, logger=logger, timeout=timeout)
self._client.start(timeout=timeout)
except Exception, e:
logging.error('Create KazooClient Failed! Exception:{}'.format(e))
# 创建Lock对象
try:
lock_path = os.path.join("/", "locks", name)
self._lock = Lock(self._client, lock_path)
except Exception, e:
logging.error('Create Lock Failed! Exception: %s'.format(e))
def __enter__(self):
"""
上下文管理器
:return:
"""
if not self.acquire():
raise Exception('Get Lock Failed')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""
上下文管理器
:param exc_type:
:param exc_val:
:param exc_tb:
:return:
"""
self.release()
def __del__(self):
"""
:return:
"""
self.release()
if self._client:
self._client.stop()
self._client = None
def acquire(self, blocking=True, timeout=None):
"""
获取锁
:param blocking:
:param timeout:
:return:
"""
if self._lock is None:
return False
try:
return self._lock.acquire(blocking=blocking, timeout=timeout)
except Exception, e:
logging.error('Acquire lock failed! Exception: %s'.format(e))
return False
def release(self):
"""
释放锁
:return:
"""
if self._lock is not None:
self._lock.release()
logging.info('Release Lock')
def main():
logger = logging.getLogger()
logger.setLevel(logging.INFO)
sh = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s -%(module)s:%(filename)s-L%(lineno)d-%(levelname)s: %(message)s')
sh.setFormatter(formatter)
logger.addHandler(sh)
hosts = "172.15.227.217:2181"
name = "test"
lock = ZKDistributedLock(hosts, name, logger=logger)
with lock:
logging.info('Get lock ok, sleep 10s')
for i in range(1, 11):
time.sleep(1)
print str(i)
logging.info('Release lock')
lock.release()
if __name__ == "__main__":
main()
http://blog.csdn.net/fragmentalice/article/details/78751664