清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
1 | 依赖zookeeper服务生成分布式一致的序列号两种方式 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | package zk.seq; import com.github.zkclient.IZkChildListener; import com.github.zkclient.ZkClient; import org.apache.zookeeper.data.Stat; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * Author : secondriver */ public class GenerateSeq { //提前创建好存储Seq的"/createSeq"结点 CreateMode.PERSISTENT public static final String SEQ_ZNODE = "/seq" ; //提前创建好锁对象的结点"/lock" CreateMode.PERSISTENT public static final String LOCK_ZNODE = "/lock" ; public static void main(String[] args) { final ExecutorService service = Executors.newFixedThreadPool( 20 ); for ( int i = 0 ; i < 20 ; i++) { service.execute( new Task2( "[Concurrent-" + i + "]" )); } if (!service.isShutdown()) { try { service.shutdown(); if (!service.awaitTermination( 10 , TimeUnit.SECONDS)) { service.shutdownNow(); } } catch (InterruptedException e) { service.shutdownNow(); System.out.println(e.getMessage()); } } } public static class Task1 implements Runnable { private final String taskName; public Task1(String taskName) { this .taskName = taskName; } @Override public void run() { ZkClient zkClient = new ZkClient( "192.168.88.153:2181" , 3000 , 1000 ); Stat stat = zkClient.writeData(SEQ_ZNODE, new byte [ 0 ], - 1 ); int versionAsSeq = stat.getVersion(); //versionAsSeq 最终的序列号 System.out.println(taskName + " obtain seq=" + versionAsSeq); zkClient.close(); } } //分布式锁实现 public static class Task2 implements Runnable, IZkChildListener { private final String taskName; private final ZkClient zkClient; private final String lockPrefix = "/loc" ; private final String selfZnode; public Task2(String taskName) { this .taskName = taskName; zkClient = new ZkClient( "192.168.88.153:2181" , 30000 , 10000 ); selfZnode = zkClient.createEphemeralSequential(LOCK_ZNODE + lockPrefix, new byte [ 0 ]); } @Override public void run() { zkClient.subscribeChildChanges(LOCK_ZNODE, this ); do { } while (zkClient.isConnected()); } private void createSeq() { Stat stat = new Stat(); byte [] oldData = zkClient.readData(LOCK_ZNODE, stat); byte [] newData = update(oldData); zkClient.writeData(LOCK_ZNODE, newData); //new String(newData) 最终的序列号 System.out.println(taskName + selfZnode + " obtain seq=" + new String(newData)); } private byte [] update( byte [] currentData) { String s = new String(currentData); int d = Integer.parseInt(s); d = d + 1 ; s = String.valueOf(d); return s.getBytes(); } @Override public void handleChildChange(String parentPath, List<String> currentChildren) throws Exception { String[] childrensZnode = currentChildren.toArray( new String[currentChildren.size()]); Arrays.sort(childrensZnode); String minZnode = LOCK_ZNODE + "/" + childrensZnode[ 0 ]; if (selfZnode.equals(minZnode)) { createSeq(); zkClient.unsubscribeChildChanges(LOCK_ZNODE, this ); zkClient.delete(selfZnode); zkClient.close(); } } } } |