Curator典型使用场景之分布式锁。

        在分布式环境中,为了保证数据的一致性,经常在程序的某个运行点(例如,减库存操作或流水号生成等)需要进行同步控制。以一个“流水号生成”的场景为例,普通的后台应用通常都是使用时间戳方式来生成流水号,但是在用户量非常大的情况下,可能会出现并发问题。下面的示例程序就演示了一个典型的并发问题。

一个典型时间戳生成的并发问题

public class Recipes_NoLock {

public static void main(String[] args) throws Exception {

final CountDownLatch down = new CountDownLatch(1);

for (int i = 0; i < 10; I ++) {

new Thread(new Runnable(){

public void run() {

try {

down.await();

} catch (Exception e) {

}

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss|SSS");

String orderNo = sdf.format(new Date());

System.err.println("生成的订单号是:" + orderNo);

}

}).start();

}

down.countDown();

}

}

        运行程序,输出结果如下:

Curator典型使用场景之分布式锁。_第1张图片

        生成的10个订单号中,有不少是重复的,如果是在实际生产环境中,这显然没有满足我们的业务需求。究其原因,就是因为在没有进行同步的情况下出现了并发问题。下面我们来看看如何使用Curator实现分布式锁功能。

使用Curator实现分布式锁功能

// 使用Curator实现分布式锁功能

public class Recipes_Lock {

static String lock_path = "/curator_recipes_lock_path";

static CuratorFramework client = CuratorFrameworkFactory.builder().connectString("domain1.book.zookeeper:2181").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 < 30; i ++) {

new Thread(new Runnable() {

public void run() {

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();

}

}

}

        运行程序,输出结果如下:

Curator典型使用场景之分布式锁。_第2张图片

        上面这个示例程序就借助Curator来实现了一个简单的分布式锁。其核心接口如下:

  • public interface InterProcessLock
    • public void acquire() throws Exception;
    • public void release() throws Exception;
        这两个接口分别用来实现分布式锁的获取与释放过程。

你可能感兴趣的:(zookeeper,分布式)