分布式共享锁
11.1 需求描述
在我們自己的分布式業務系統中,可能會存在某種資源,需要被整個系統的各臺服務器共享訪問,但是只允許一臺服務器同時訪問
?
11.2 設計思路
?
11.3 代碼開發
?
public class DistributedClientMy { ???? // 超時時間 ???? private static final int SESSION_TIMEOUT = 5000; ???? // zookeeper server列表 ???? private String hosts = "spark01:2181,spark02:2181,spark03:2181"; ???? private String groupNode = "locks"; ???? private String subNode = "sub"; ???? private boolean haveLock = false; ? ???? private ZooKeeper zk; ???? // 當前client創建的子節點 ???? private volatile String thisPath; ? ???? /** ???? ?* 連接zookeeper ???? ?*/ ???? public void connectZookeeper() throws Exception { ???? ???? zk = new ZooKeeper("spark01:2181", SESSION_TIMEOUT, new Watcher() { ???? ???? ???? public void process(WatchedEvent event) { ???? ???? ???? ???? try { ? ???? ???? ???? ???? ???? // 子節點發生變化 ???? ???? ???? ???? ???? if (event.getType() == EventType.NodeChildrenChanged && event.getPath().equals("/" + groupNode)) { ???? ???? ???? ???? ???? ???? // thisPath是否是列表中的最小節點 ???? ???? ???? ???? ???? ???? List<String> childrenNodes = zk.getChildren("/" + groupNode, true); ???? ???? ???? ???? ???? ???? String thisNode = thisPath.substring(("/" + groupNode + "/").length()); ???? ???? ???? ???? ???? ???? // 排序 ???? ???? ???? ???? ???? ???? Collections.sort(childrenNodes); ???? ???? ???? ???? ???? ???? if (childrenNodes.indexOf(thisNode) == 0) { ???? ???? ???? ???? ???? ???? ???? doSomething(); ???? ???? ???? ???? ???? ???? ???? thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE, ???? ???? ???? ???? ???? ???? ???? ???? ???? CreateMode.EPHEMERAL_SEQUENTIAL); ???? ???? ???? ???? ???? ???? } ???? ???? ???? ???? ???? } ???? ???? ???? ???? } catch (Exception e) { ???? ???? ???? ???? ???? e.printStackTrace(); ???? ???? ???? ???? } ???? ???? ???? } ???? ???? }); ? ???? ???? // 創建子節點 ???? ???? thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE, ???? ???? ???? ???? CreateMode.EPHEMERAL_SEQUENTIAL); ? ???? ???? // wait一小會, 讓結果更清晰一些 ???? ???? Thread.sleep(new Random().nextInt(1000)); ? ???? ???? // 監聽子節點的變化 ???? ???? List<String> childrenNodes = zk.getChildren("/" + groupNode, true); ? ???? ???? // 列表中只有一個子節點, 那肯定就是thisPath, 說明client獲得鎖 ???? ???? if (childrenNodes.size() == 1) { ???? ???? ???? doSomething(); ???? ???? ???? thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE, ???? ???? ???? ???? ???? CreateMode.EPHEMERAL_SEQUENTIAL); ???? ???? } ???? } ? ???? /** ???? ?* 共享資源的訪問邏輯寫在這個方法中 ???? ?*/ ???? private void doSomething() throws Exception { ???? ???? try { ???? ???? ???? System.out.println("gain lock: " + thisPath); ???? ???? ???? Thread.sleep(2000); ???? ???? ???? // do something ???? ???? } finally { ???? ???? ???? System.out.println("finished: " + thisPath); ???? ???? ???? // 將thisPath刪除, 監聽thisPath的client將獲得通知 ???? ???? ???? // 相當于釋放鎖 ???? ???? ???? zk.delete(this.thisPath, -1); ???? ???? } ???? } ? ???? public static void main(String[] args) throws Exception { ???? ???? DistributedClientMy dl = new DistributedClientMy(); ???? ???? dl.connectZookeeper(); ???? ???? Thread.sleep(Long.MAX_VALUE); ???? } ? ???? } |
總結
- 上一篇: 恩施梭布垭有军人优待证免门票吗?
- 下一篇: 讯维应急指挥车系统一般是由哪些部分组成的