Zookeeper案例之分布式全局唯一ID生成

目录

一、概述

二、案例实现


一、概述

在单体架构中,我们通常使用数据库字段自带的自增auto_increment属性来自动为每一条记录生成唯一的ID,但是当我们采用分布式系统后,特别是分库分表后,就无法再依靠数据库的auto_increment属性来唯一标识一条记录,这就需要采用其他方法来生成全局唯一ID。

在zookeeper中,它提供了一种以创建临时有序节点来获取到全局唯一ID,它能保证在整个分布式系统中的全局唯一性。

下面我们通过一个简单的案例来说明如何利用zookeeper生成全局唯一ID。

二、案例实现

实现步骤:

  • 1、客户端连接到zookeeper服务器端;
  • 2、客户端在指定路径下生成临时有序节点;
  • 3、取出序列号,这就是分布式全局唯一ID;

具体案例代码如下:

import org.apache.zookeeper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class ZookeeperUniqueID {
    private static final String ZOOKEEPER_SERVER_ADDRESS = "192.168.179.133:2181";
    private static final Logger logger = LoggerFactory.getLogger(ZookeeperUniqueID.class);
    private static ZooKeeper zooKeeper = null;
    /**
     * 用户生成序号的节点
     */
    private static final String NODE_PREFIX = "/unique_id";

    public ZookeeperUniqueID() {
        try {
            Watcher watcher = new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    try {
                        // 捕获事件状态
                        if (event.getType() == Event.EventType.None) {
                            if (event.getState() == Event.KeeperState.SyncConnected) {
                                logger.info("连接成功...");
                            } else if (event.getState() == Event.KeeperState.Disconnected) {
                                logger.info("连接断开...");
                            } else if (event.getState() == Event.KeeperState.Expired) {
                                logger.info("连接超时...");
                                // 超时后服务器端已经将连接释放,需要重新连接服务器端
                                zooKeeper = new ZooKeeper(ZOOKEEPER_SERVER_ADDRESS, 3000, this);
                            } else if (event.getState() == Event.KeeperState.AuthFailed) {
                                logger.info("验证失败...");
                            }
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            };
            zooKeeper = new ZooKeeper(ZOOKEEPER_SERVER_ADDRESS, 3000, watcher);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getUniqueID() {
        try {
            //创建临时有序节点
            String path = zooKeeper.create(NODE_PREFIX, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            logger.info("path: " + path);
            return path.substring(NODE_PREFIX.length());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        ZookeeperUniqueID zookeeperUniqueID = new ZookeeperUniqueID();
        for (int i = 0; i < 10; i++) {
            System.out.println("分布式唯一ID:" + zookeeperUniqueID.getUniqueID());
        }
    }

}

运行结果:

11:34:10.336 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000029
分布式唯一ID:0000000029
11:34:10.338 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 2,1  replyHeader:: 2,276,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000030 
11:34:10.338 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000030
分布式唯一ID:0000000030
11:34:10.339 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 3,1  replyHeader:: 3,277,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000031 
11:34:10.339 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000031
分布式唯一ID:0000000031
11:34:10.341 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 4,1  replyHeader:: 4,278,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000032 
11:34:10.341 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000032
分布式唯一ID:0000000032
11:34:10.343 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 5,1  replyHeader:: 5,279,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000033 
11:34:10.343 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000033
分布式唯一ID:0000000033
11:34:10.345 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 6,1  replyHeader:: 6,280,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000034 
11:34:10.345 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000034
分布式唯一ID:0000000034
11:34:10.346 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 7,1  replyHeader:: 7,281,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000035 
11:34:10.346 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000035
分布式唯一ID:0000000035
11:34:10.348 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 8,1  replyHeader:: 8,282,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000036 
11:34:10.348 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000036
分布式唯一ID:0000000036
11:34:10.349 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 9,1  replyHeader:: 9,283,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000037 
11:34:10.349 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000037
分布式唯一ID:0000000037
11:34:10.350 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f0025, packet:: clientPath:null serverPath:null finished:false header:: 10,1  replyHeader:: 10,284,0  request:: '/unique_id,,v{s{31,s{'world,'anyone}}},3  response:: '/unique_id0000000038 
11:34:10.350 [main] INFO com.wsh.zookeeper.zookeeperapidemo.uniqueid.ZookeeperUniqueID - path: /unique_id0000000038
分布式唯一ID:0000000038

以上就是关于如何在zookeeper中生成分布式环境下全局唯一ID,在工作中,如果有需要生成全局唯一ID的场景,也可以采用zookeeper来实现,当然还有其他算法也可以生成全局唯一ID,有兴趣的小伙伴可以去研究研究。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值