zookeeper是一种分布式协调服务,用于管理大型主机。在分布式环境中协调和管理服务是一个复杂的过程,ZooKeeper通过其简单的架构和API解决了这个问题。Zookeeper允许开发人员专注于核心应用程序逻辑,而不必担心应用程序的分布式特性。
docker search zookeeper
docker pull zookeeper
#创建一个虚拟网络
docker network create mynetwork
#查看创建的虚拟网络
docker network inspect mynetwork
#三个zk节点,总共创建三个目录,用于映射/conf和/data目录
mkdir -m777 /Users/a1/develop/docker/zookeeper/zk1
mkdir -m777 /Users/a1/develop/docker/zookeeper/zk2
mkdir -m777 /Users/a1/develop/docker/zookeeper/zk3
docker run -d --network mynetwork --name zk1 -p 2181:2181 \
-v /Users/a1/develop/docker/zookeeper/zk1/conf:/conf \
-v /Users/a1/develop/docker/zookeeper/zk1/data:/data \
zookeeper
docker run -d --network mynetwork --name zk2 -p 2182:2181 \
-v /Users/a1/develop/docker/zookeeper/zk2/conf:/conf \
-v /Users/a1/develop/docker/zookeeper/zk2/data:/data \
zookeeper
docker run -d --network mynetwork --name zk3 -p 2183:2181 \
-v /Users/a1/develop/docker/zookeeper/zk3/conf:/conf \
-v /Users/a1/develop/docker/zookeeper/zk3/data:/data \
zookeeper
docker run -d --network mynetwork --name zk4 -p 2184:2181 \
-v /Users/a1/develop/docker/zookeeper/zk4/conf:/conf \
-v /Users/a1/develop/docker/zookeeper/zk4/data:/data \
zookeeper
#修改各自的myid文件中的值为1、2、3
echo 1 > myid
echo 2 > myid
echo 3 > myid
#zoo.cfg 文件中修改如下
dataDir=/data
dataLogDir=/datalog
tickTime=2000
initLimit=5
syncLimit=2
autopurge.snapRetainCount=3
autopurge.purgeInterval=0
maxClientCnxns=60
standaloneEnabled=true
admin.enableServer=true
#server.1=localhost:2888:3888;2181
server.1=192.168.228.2:2001:3001;2181
server.2=192.168.228.3:2001:3001;2181
server.3=192.168.228.4:2001:3001;2181
docker start zk1
docker start zk2
docker start zk3
至此,使用docker构建zk集群完成,按照zk的ZAB协议,以1、2、3的顺序启动zk节点,则myid为2的节点为集群的leader,其它两个为follower
<!-- 引入Curator的依赖-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
//springboot 配置文件,载入CuratorTemplate组件
@org.springframework.context.annotation.Configuration
@ComponentScan(basePackages = "com.huwc.mvclearn")
public class Configuration {
@Bean
CuratorFramework curatorFramework(){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
CuratorFramework curatorFramework = CuratorFrameworkFactory.builder().
connectString("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183").sessionTimeoutMs(100 * 1000).retryPolicy(retryPolicy).build();
curatorFramework.start();
System.out.println("curatorFramework.isStarted() = " + curatorFramework.isStarted());
return curatorFramework ;
}
}
//测试读锁和写锁的代码:
@Autowired
private CuratorFramework curatorFramework ;
@Test
public void testReadLock() throws Exception {
InterProcessReadWriteLock lock = new InterProcessReadWriteLock(curatorFramework, "/lock1");
// 获取读锁
InterProcessMutex readLock = lock.readLock();
readLock.acquire();
// 模拟读取操作
for(int i=0;i<100;i++){
System.out.println(i+"读取中...");
Thread.sleep(3000);
}
readLock.release();
}
@Test
public void testWriteLock() throws Exception {
InterProcessReadWriteLock lock = new InterProcessReadWriteLock(curatorFramework, "/lock1");
// 获取写锁
InterProcessMutex writeLock = lock.writeLock();
writeLock.acquire();
System.out.println("writeLock getted.......");
writeLock.release();
}
分布式锁可以采用redis或者zookeeper的特性来实现,但redis的机制是ap而zookeeper的机制是cp,所以在极端情况下,redis的分布式锁可能会出现问题,但zookeeper的锁相对更加安全。