利用zookeeper生成唯一id
package com.cxy.com.cxy.curator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.I0Itec.zkclient.ZkClient; import org.I0Itec.zkclient.exception.ZkNodeExistsException; import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer; /** * @Author cxy * @Description //TODO * @Date 2019/1/30 **/ public class IdMaker { private ZkClient client = null; private final String server ="127.0.0.1:2181";//记录服务器的地址 private final String root ="/NameService/IdGen";//记录父节点的路径 private final String nodeName="ID";//节点的名称 private volatile boolean running = false; private ExecutorService cleanExector = null; //删除节点的级别 public enum RemoveMethod{ NONE,IMMEDIATELY,DELAY } public void start() throws Exception { if (running) throw new Exception("server has stated..."); running = true; init(); } public void stop() throws Exception { if (!running) throw new Exception("server has stopped..."); running = false; freeResource(); } /** * 初始化服务资源 */ private void init(){ client = new ZkClient(server,5000,5000,new BytesPushThroughSerializer()); cleanExector = Executors.newFixedThreadPool(10); try{ client.createPersistent(root,true); }catch (ZkNodeExistsException e){ //ignore; } } /** * 释放服务资源 */ private void freeResource(){ cleanExector.shutdown(); try{ cleanExector.awaitTermination(2, TimeUnit.SECONDS); }catch(InterruptedException e){ e.printStackTrace(); }finally{ cleanExector = null; } if (client!=null){ client.close(); client=null; } } /** * 检测服务是否正在运行 * @throws Exception */ private void checkRunning() throws Exception { if (!running) throw new Exception("请先调用start"); } private String ExtractId(String str){ int index = str.lastIndexOf(nodeName); if (index >= 0){ index+=nodeName.length(); return index <= str.length()?str.substring(index):""; } return str; } /** * 产生ID * 核心函数 * @param removeMethod 删除的方法 * @return * @throws Exception */ public String generateId(RemoveMethod removeMethod) throws Exception{ checkRunning(); final String fullNodePath = root.concat("/").concat(nodeName); //返回创建的节点的名称 //final String ourPath = client.createPersistentSequential(fullNodePath, null); final String ourPath = client.createEphemeralSequential(fullNodePath, null); System.out.println(ourPath); /** * 在创建完节点后为了不占用太多空间,可以选择性删除模式 */ if (removeMethod.equals(RemoveMethod.IMMEDIATELY)){ client.delete(ourPath); }else if (removeMethod.equals(RemoveMethod.DELAY)){ cleanExector.execute(new Runnable() { public void run() { // TODO Auto-generated method stub client.delete(ourPath); } }); } //node-0000000000, node-0000000001,ExtractId提取ID return ExtractId(ourPath); } }
这个是工具类
package com.cxy.com.cxy.curator; /*** * @ClassName: TestIdMaker * @Description: * @Auther: cxy * @Date: 2019/1/30:17:15 * @version : V1.0 */ public class TestIdMaker { public static void main(String[] args) throws Exception { IdMaker idMaker = new IdMaker(); idMaker.start(); try { for (int i = 0; i < 10111; i++) { String id = idMaker.generateId(IdMaker.RemoveMethod.NONE); System.out.println(id); } } finally { idMaker.stop(); } } }
这个是测试类
可以看出是唯一的,那么在电商生产中可以加上分库分表的id+在模块+userid,加上日期就是唯一的了,不管是任何请求这个id都是唯一的,即使是在分布式环境下
笔记转移,由于在有道云的笔记转移,写的时间可能有点久,如果有错误的地方,请指正