zookeeper Curator 场景应用

来源:互联网 发布:日本好听的歌 知乎 编辑:程序博客网 时间:2024/06/07 00:28

分布式锁功能:

在分布式场景中,我们为了保证数据的一致性,经常在程序运行的某一个点需要进行同步操作(java可提供synchronzied或者reentrantlock),分布式不同步的问题:

因为我们之前所说的是在高并发下访问程序,现在我们则是在高并发下访问多个服务器节点

我们使用 curator基于zookeeper的特性提供分布式锁来处理分布式场景的数据一致性,zookeeper本身的分布式是有写问题的

我们用代码来模拟实现一下:

package bjsxt.curator.lock;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.CountDownLatch;import java.util.concurrent.locks.ReentrantLock;import org.apache.curator.RetryPolicy;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;public class Lock2 {/** zookeeper地址 */static final String CONNECT_ADDR = "192.168.1.171:2181,192.168.1.172:2181,192.168.1.173:2181";/** session超时时间 */static final int SESSION_OUTTIME = 5000;//ms static int count = 10;public static void genarNo(){try {count--;System.out.println(count);} finally {}}public static void main(String[] args) throws Exception {//1 重试策略:初试时间为1s 重试10次RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);//2 通过工厂创建连接CuratorFramework cf = CuratorFrameworkFactory.builder().connectString(CONNECT_ADDR).sessionTimeoutMs(SESSION_OUTTIME).retryPolicy(retryPolicy)//.namespace("super").build();//3 开启连接cf.start();//4 分布式锁final InterProcessMutex lock = new InterProcessMutex(cf, "/super");//final ReentrantLock reentrantLock = new ReentrantLock();final CountDownLatch countdown = new CountDownLatch(1);for(int i = 0; i < 10; i++){new Thread(new Runnable() {@Overridepublic void run() {try {countdown.await();//加锁lock.acquire();//reentrantLock.lock();//-------------业务处理开始//genarNo();SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss|SSS");System.out.println(sdf.format(new Date()));//System.out.println(System.currentTimeMillis());//-------------业务处理结束} catch (Exception e) {e.printStackTrace();} finally {try {//释放lock.release();//reentrantLock.unlock();} catch (Exception e) {e.printStackTrace();}}}},"t" + i).start();}Thread.sleep(100);countdown.countDown(); }}

分布式计数器功能:

一说到分布式计数器,你可能脑海里想到了AtomicInteger这中经典的方式,如果针对一个jvm 的场景当然没问题,但是我们现在是分布式场景下,就需要利用Curator框架的DistrbutedAtomicInteger了。


package bjsxt.curator.atomicinteger;import org.apache.curator.RetryPolicy;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;public class CuratorAtomicInteger {/** zookeeper地址 */static final String CONNECT_ADDR = "192.168.1.128:2181,192.168.1.131:2181,192.168.1.130:2181";/** session超时时间 */static final int SESSION_OUTTIME = 5000;//ms public static void main(String[] args) throws Exception {//1 重试策略:初试时间为1s 重试10次RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);//2 通过工厂创建连接CuratorFramework cf = CuratorFrameworkFactory.builder().connectString(CONNECT_ADDR).sessionTimeoutMs(SESSION_OUTTIME).retryPolicy(retryPolicy).build();//3 开启连接cf.start();//cf.delete().forPath("/super");//4 使用DistributedAtomicIntegerDistributedAtomicInteger atomicIntger = new DistributedAtomicInteger(cf, "/super", new RetryNTimes(3, 1000));AtomicValue<Integer> value = atomicIntger.add(1);System.out.println(value.succeeded());System.out.println(value.postValue());//最新值System.out.println(value.preValue());//原始值}}


输出结果:

log4j:WARN No appenders could be found for logger (org.apache.curator.CuratorZookeeperClient).log4j:WARN Please initialize the log4j system properly.true10


DistributedBarrier 、DistributedDoubleBarrier

package bjsxt.curator.barrier;import java.text.SimpleDateFormat;import java.util.Date;import org.apache.curator.RetryPolicy;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.framework.recipes.barriers.DistributedBarrier;import org.apache.curator.framework.recipes.queue.DistributedQueue;import org.apache.curator.retry.ExponentialBackoffRetry;import org.apache.curator.retry.RetryNTimes;public class CuratorBarrier2 {/** zookeeper地址 */static final String CONNECT_ADDR = "192.168.1.131:2181,192.168.1.128:2181,192.168.1.130:2181";/** session超时时间 */static final int SESSION_OUTTIME = 5000;//ms static DistributedBarrier barrier = null;public static void main(String[] args) throws Exception {for(int i = 0; i < 5; i++){new Thread(new Runnable() {@Overridepublic void run() {try {RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);CuratorFramework cf = CuratorFrameworkFactory.builder().connectString(CONNECT_ADDR).sessionTimeoutMs(SESSION_OUTTIME).retryPolicy(retryPolicy).build();cf.start();barrier = new DistributedBarrier(cf, "/super");System.out.println(Thread.currentThread().getName() + "设置barrier!");barrier.setBarrier();//设置barrier.waitOnBarrier();//等待System.out.println("---------开始执行程序----------");} catch (Exception e) {e.printStackTrace();}}},"t" + i).start();}Thread.sleep(5000);barrier.removeBarrier();//释放}}


package bjsxt.curator.barrier;import java.util.Random;import org.apache.curator.RetryPolicy;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.framework.recipes.barriers.DistributedDoubleBarrier;import org.apache.curator.retry.ExponentialBackoffRetry;public class CuratorBarrier1 {/** zookeeper地址 */static final String CONNECT_ADDR = "192.168.1.128:2181,192.168.1.130:2181,192.168.1.131:2181";/** session超时时间 */static final int SESSION_OUTTIME = 5000;//ms public static void main(String[] args) throws Exception {for(int i = 0; i < 5; i++){new Thread(new Runnable() {@Overridepublic void run() {try {RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);CuratorFramework cf = CuratorFrameworkFactory.builder().connectString(CONNECT_ADDR).retryPolicy(retryPolicy).build();cf.start();DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(cf, "/super", 5);Thread.sleep(1000 * (new Random()).nextInt(3)); System.out.println(Thread.currentThread().getName() + "已经准备");barrier.enter();System.out.println("同时开始运行...");Thread.sleep(1000 * (new Random()).nextInt(3));System.out.println(Thread.currentThread().getName() + "运行完毕");barrier.leave();System.out.println("同时退出运行...");} catch (Exception e) {e.printStackTrace();}}},"t" + i).start();}}}


0 0