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都是唯一的,即使是在分布式環境下