ZooKeeper典型使用場景

先須要下載 curator 的依賴包java

分佈式鎖

在分佈式環境中,爲了保證數據的一致性,常常在程序的某個運行點須要進行同步控制。併發

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
import com.google.common.cache.CacheBuilder;


class DistributedLock {
    
    static String lock_path = "/curator_recipes_lock_path";
    static CuratorFramework client = CuratorFrameworkFactory.builder()
            .connectString("202.201.13.*:2100")
            .retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
    
    public static void main(String[] args) throws Exception {
        client.start();
        final InterProcessMutex lock = new InterProcessMutex(client, lock_path);
        final CountDownLatch down = new CountDownLatch(1);
        
        for(int i = 0; i < 10; i++){
            new Thread(new Runnable() {
                public void run() {
                    try {
                        down.await();
                        lock.acquire();
                    } catch ( Exception e ) {}
                    
                    SimpleDateFormat sdf  = new SimpleDateFormat("HH:mm:ss|SSS");
                    String orderNo = sdf.format(new Date());
                    
                    System.out.println("生成的訂單號是: " + orderNo);
                    try {
                        lock.release();
                    } catch ( Exception e ) {}
                }
            }).start();
        }
        down.countDown();
    }
}

CountDownLatch 類是一個同步計數器,每調用一次countDown()方法,計數器減1,計數器大於0 時,await()方法會阻塞程序繼續執行。它是一個倒計數的鎖存器,當計數減至0時觸發特定的事件。利用這種特性,可讓主線程等待子線程的結束。maven

在這裏的做用是讓 10 個子進程先阻塞在一個 down.await(),以便後面模擬高併發。父進程一旦執行 down.countDown(),10 個子進程開始搶鎖。分佈式

而爲了讓 10 個子進程不形成資源競爭,須要使用 InterProcessLock 進行同步。高併發

public interface InterProcessLock
  -public void acquire() throws Exception;
  -public void release() throws Exception;

打印結果ui

生成的訂單號是: 21:06:29|951
生成的訂單號是: 21:06:29|981
生成的訂單號是: 21:06:30|007
生成的訂單號是: 21:06:30|023
生成的訂單號是: 21:06:30|039
生成的訂單號是: 21:06:30|062
生成的訂單號是: 21:06:30|076
生成的訂單號是: 21:06:30|096
生成的訂單號是: 21:06:30|107
生成的訂單號是: 21:06:30|148

分佈式計數器

分佈式計數器能夠用來統計系統的在線人數。思路是指定一個 ZooKeeper 節點做爲計數器,多個應用實例在分佈式鎖的控制下,遞增數據節點的計數值。google

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.atomic.AtomicValue;
import org.apache.curator.framework.recipes.atomic.DistributedAtomicInteger;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.retry.RetryNTimes;

class Recipes_DisAtomicInt {
    
    static String distatomicint_path = "/curator_recipes_distatomicint_path";
    static CuratorFramework client = CuratorFrameworkFactory.builder()
            .connectString("202.201.13.*:2100")
            .retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
    
    public static void main(String[] args) throws Exception {
        client.start();
        DistributedAtomicInteger atomicInterger = 
        new DistributedAtomicInteger( client, distatomicint_path, new RetryNTimes(3, 1000));
        
        AtomicValue<Integer> rc = atomicInterger.add(1);
        System.out.println("Result: " + rc.succeeded());
    }
}

使用客戶端腳原本鏈接服務器查看計數值

bash zkCli.sh -server 127.0.0.1:2100

輸入圖片說明

能夠看到節點數據從 1A 增到 1B。

相關文章
相關標籤/搜索