Curator basic operation notes

Classification

Zookeeper client

Create ZKClient

The specific implementation of ZKClient in Curator is CuratorFrameWork, which can be constructed by constructor and Fluent.

CuratorFrameWork

public CuratorFramework getCurator(){
        CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
                .connectString("127.0.0.1:2181")
                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(1000)
                .retryPolicy(new ExponentialBackoffRetry(1000,3))
                .build();
        Assertions.assertThat(curatorFramework).isNotNull();
        return curatorFramework;
}

retryPolicy

The parameter RetryPolicy refers to the retry policy when the CuratorFramework connects. To implement a custom RetryPolicy, the allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper)method needs to be rewritten.
Here I use the ExponentialBackoffRetry class provided by Curator, which integrates SleepingRetry, a subclass of RetryPolicy, and retries each time. Will randomly extend the basic sleep time for a period of time, the specific code is as follows:

   @Override
    protected int getSleepTimeMs(int retryCount, long elapsedTimeMs)
    {
        // copied from Hadoop's RetryPolicies.java
        int sleepMs = baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)));
        if ( sleepMs > maxSleepMs )
        {
            log.warn(String.format("Sleep extension too large (%d). Pinning to %d", sleepMs, maxSleepMs));
            sleepMs = maxSleepMs;
        }
        return sleepMs;
    }

The Curator version is compatible with the Zookeeper version

The Curator3.* version only supports the Zookeeper3.5.* version. There are two ways to use the 3.4.* version:

  1. Replace with lower version Curator2.*
  2. Remove the built-in zookeeper dependency in the dependency, the specific pom is as follows:
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>${curator-version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </exclusion>
    </exclusions>
</dependency>

zooKeeper basic operations

The basic operations of zooKeeper are all performed using unit tests written by junit.

Synchronously create, delete and view nodes

@Test
    void createNodeAndDeleteNodeTest() throws Exception {
        //创建节点
        String path = curatorFramework.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL)
                .forPath("/test/123", "test".getBytes());
        Assertions.assertThat(path).isEqualTo("/test/123");
        //获取节点数据以及节点状态
        Stat stat = new Stat();
        String data = new String(curatorFramework.getData()
                .storingStatIn(stat)
                .forPath("/test/123"));
        Assertions.assertThat(stat).isNotNull();
        Assertions.assertThat(data).isEqualTo("test");
        //修改节点数据
        curatorFramework.setData().withVersion(stat.getVersion()).forPath("/test/123", "test123".getBytes());
        Assertions.assertThat(new String(curatorFramework.getData()
                .storingStatIn(stat)
                .forPath("/test/123"))).isEqualTo("test123");
        //获取子节点
        List<String> children = curatorFramework.getChildren().forPath("/test");
        Assertions.assertThat(children).contains("123");
        //删除节点
        curatorFramework.delete()
                .guaranteed()
                .deletingChildrenIfNeeded()
                .forPath("/test");
        Assertions.assertThat(curatorFramework.checkExists().forPath("/test/123")).isNull();
    }

Asynchronously create delete view node

@Test
    void asyncCreateNodeAndDeleteNodeTest() throws Exception {
        //线程池
        ExecutorService service = Executors.newFixedThreadPool(5);
        //创建节点
        curatorFramework.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL)
                .inBackground((arg0, arg1) ->
                        {
                            Assertions.assertThat(arg1.getPath()).isEqualTo("/test/123");
                            Assertions.assertThat(arg1.getType()).isEqualTo(CuratorEventType.CREATE);
                            Assertions.assertThat(arg1.getContext()).isEqualTo("123");
                        }
                        , "123", service)
                .forPath("/test/123", "test".getBytes());
        //修改节点数据
        curatorFramework.setData()
                .inBackground((arg0, arg1) ->
                {
                    Assertions.assertThat(arg1.getType()).isEqualTo(CuratorEventType.SET_DATA);
                }, service)
                .forPath("/test/123", "test123".getBytes());
        //获取子节点
        curatorFramework.getChildren().inBackground((arg0, arg1) ->
                {
                    Assertions.assertThat(arg1.getChildren()).contains("123");
                    Assertions.assertThat(arg1.getType()).isEqualTo(CuratorEventType.CHILDREN);
                }
                , service).forPath("/test");
        //删除节点
        curatorFramework.delete()
                .guaranteed()
                .deletingChildrenIfNeeded()
                .forPath("/test");
        Assertions.assertThat(curatorFramework.checkExists().forPath("/test/123")).isNull();
        service.shutdown();
    }

Node data event listener

    @Test
    void nodeListenerTest() throws Exception {
        NodeCache cache = new NodeCache(curatorFramework, "/test/123");
        cache.start();
        cache.getListenable().addListener(() -> {
            log.info(new String(cache.getCurrentData().getData()));
        });
        curatorFramework.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL)
                .forPath("/test/123", "test".getBytes());
        for (int i = 0; i < 10; i++) {
            curatorFramework.setData().forPath("/test/123", String.valueOf(Math.random()).getBytes());
            Thread.sleep(1000);
        }
        curatorFramework.delete()
                .guaranteed()
                .deletingChildrenIfNeeded()
                .forPath("/test");
        Assertions.assertThat(curatorFramework.checkExists().forPath("/test/123")).isNull();

    }

child node event listener

    @Test
    void nodeChildrenListenerTest() throws Exception {
        PathChildrenCache cache = new PathChildrenCache(curatorFramework, "/test/123", true);
        cache.start();
        cache.getListenable().addListener((client, event) -> {
            switch (event.getType()) {
                case CHILD_ADDED:
                    log.info("child_added "+event.getData());
                    break;
                case CHILD_REMOVED:
                    log.info("child_added "+event.getData());
                    break;
                case CHILD_UPDATED:
                    log.info("child_added "+event.getData());
                    break;
                default:
                    log.info("other event "+event.getData());
            }
        });
        for (int i = 0; i < 10; i++) {
            curatorFramework.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.EPHEMERAL)
                    .forPath("/test/123/"+String.valueOf(Math.random()), "test".getBytes());
            Thread.sleep(1000);
        }
        curatorFramework.delete()
                .guaranteed()
                .deletingChildrenIfNeeded()
                .forPath("/test");
        Assertions.assertThat(curatorFramework.checkExists().forPath("/test/123")).isNull();
    }

Leader Election Example

Fundamental

service start

1. Each service node maintains a connection with Zookeeper and registers itself with the node/child/service ID.
2. Determine whether there is currently a Master. If not, try to register as a Master node. If it fails, query the master node again and record the master data.
3. During the registration process, if you find that the previous Master node is not yourself, delay Registration is being performed for a period of time to avoid frequent ownership changes caused by network jitter.
4. Set the listener of the master node. When the event of node deletion is received, the operation of competing for the master node is performed again.

service shut down

Delete the node to see if it is the master node, if so, release the node

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325987170&siteId=291194637