大数据学习(十五)zookeeperAPI操作 zookeeper分布式锁

zookeeperAPI

package zkApI;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

/**
 * @Author: Braylon
 * @Date: 2020/1/30 10:47
 * @Version: 1.0
 */
public class zookeeper {
    //对集群的配置,这里使用伪分布
    private static String destination = "ip:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zkClient = null;

    @Before
    public void init() throws IOException {
        zkClient = new ZooKeeper(destination, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //收到事件通知后执行的函数,也就似乎用户的业务逻辑
                System.out.println("监听" + "\001" + watchedEvent.getPath());

                //重新开始监听
                try {
                    zkClient.getChildren("/", true);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Test
    public void crearePoint() {
        /*对于create方法
        * P1:创建的节点路径
        * P2:数据
        * P3:节点的权限
        * P4:节点的类型
        * */
        try {
            zkClient.create("/braylon", "point01".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void getChild() {
        try {
            List<String> children = zkClient.getChildren("/", true);
            for (String c : children) {
                System.out.println(c);
            }
            //延时阻塞
            Thread.sleep(Long.MAX_VALUE);

        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void isExited() {
        try {
            Stat s = zkClient.exists("/braylon", false);
            System.out.println(s == null ? "不存在" : "存在");
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

这里其实没有什么特别好说的,因为基本上都是很简单的操作,不过可以可以关注一下,@Before这个并不是zookeeper开发包中的,而是junit中的,答题的逻辑就是在运行Test之前先运行@Before注解下的监听器。

大家运行一些就明白了。

分布式锁

分布式锁一共有三种无非是利用原子性操作来达到。

  1. 数据库
  2. redis
  3. zookeeper锁

都可以实现分布式锁,

我知道的是redis用的好像比较多,当然我在上本科,所以也许是没有接触过特别高逼格的分布式锁。但是我一直觉得zookeeper锁使用比redis更加简单,主要应该是本身zookeeper的机制和开发包的封装性已经非常“傻瓜了”。

这里我分享一个小demo:

我使用的就是一个本地部署zookeeper的虚拟机,哈哈很简单吧。

package zkApI;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessLock;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

/**
 * @Author: Braylon
 * @Date: 2020/1/30 11:23
 * @Version: 1.0
 */
public class zkDistributionLock {
    private static Integer sharedResource = 5;

    public static void print() {
        System.out.println("**************" + Thread.currentThread().getName() + "**************");
        System.out.println("Get sharedResource");
        if (sharedResource == 0) {
            System.out.println("sorry, your operation fails");
            return;
        }
        sharedResource = sharedResource - 1;
        System.out.println("left " + sharedResource);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("************************done\n");
    }

    public static void main(String[] args) {
        //等待时间和最大重试次数
        ExponentialBackoffRetry policy = new ExponentialBackoffRetry(1000, 10);

        CuratorFramework client = CuratorFrameworkFactory.builder().connectString("ip:2181").retryPolicy(policy).build();
        //生成锁
        client.start();
        final InterProcessMutex mutex = new InterProcessMutex(client, "/lock0130");
        //多线程并发访问
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //在访问共享资源之前获得锁
                        mutex.acquire();
                        print();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        //释放锁
                        try {
                            mutex.release();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }
}

欢迎大神指点
祝福武汉
大家共勉~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章