Zookeeper Python应用 - 独占分布式锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 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

猜你喜欢

转载自blog.csdn.net/dogpig945/article/details/78751664
今日推荐