Zookeeper是基于观察者模式设计的分布式服务协调管理框架,Zookeeper = 文件系统 + 通信机制。
文件系统 : 管理前是不是要先登记信息呀,所以它有服务注册发现功能(注册中心),存储服务之间的数据;
通信机制 : 管理肯定涉及一些操作,当记录的数据发生变化时,是不是要调用相应的回调函数;
因为服务一般是集群部署,有时候不需要所有机器同时触发某逻辑,是不是需要分布式锁支持,所以Zookeeper自己也实现一套分布式锁。。。。。。比如Kafka集群得Controller选举机制,"先到先得"
Zookeeper集群只要有大于半数的节点存活,才能正常工作,所以Zookeeper集群一般是奇数部署
其它功能:
1.域名解析: www.xxxx.com --> 192.168.208.111,192.168.208.112 ...
2.配置中心:上面说了注册中心,zk还有统一配置的功能
-
健康检测: zk的客户端(被管理的微服务)是否处于正常工作状态,发送警告短信给运维人员
-
动态路由:因为有健康检测,如果请求访问了zk下线的客户端,会将请求转发到健康的zk客户端
-
分布式锁:序号越小优先级越高,代表获取到锁(公平锁),Client1操作完 或者 挂掉了将msg1清除(释放锁);扩展一下利用Mysql 的主键唯一索引和行级锁机制(并发操作同一行数据,会自动加锁)也可以实现分布式锁
javascript
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-client -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.3.0</version>
</dependency>
java
package com.ldj.lockdemo;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* User: ldj
* Date: 2024/10/13
* Time: 3:03
* Description: ZK客户端Demo
*/
public class DistributedLock {
public static void main(String[] args) throws Exception {
InterProcessMutex lock1 = new InterProcessMutex(getConnection(), "/lock_test");
new Thread(() -> {
try {
lock1.acquire();
System.out.println("[" + Thread.currentThread().getId() + "] >>>>>>>> 获取锁");
lock1.acquire();
System.out.println("[" + Thread.currentThread().getId() + "] >>>>>>>> 再次获得锁,说明是可重入锁");
lock1.release();
System.out.println("[" + Thread.currentThread().getId() + "] >>>>>>>> 释放锁");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private static CuratorFramework getConnection() {
// 设置超时策略
ExponentialBackoffRetry policy = new ExponentialBackoffRetry(3000, 3);
CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
.connectString("192.168.208.200:2181")
.connectionTimeoutMs(60000) // 一般在30~45秒
.sessionTimeoutMs(60000)
.retryPolicy(policy)
.authorization("digest", "user:password".getBytes())
.build();
ConnectionStateListener listener = (client, newState) -> {
if (newState == ConnectionState.CONNECTED) {
System.out.println(">>>>>>>> zookeeper successfully connected!");
}
};
// 设置监听回调
curatorFramework.getConnectionStateListenable().addListener(listener);
curatorFramework.start();
System.out.println(">>>>>>>> zookeeper is connecting...");
return curatorFramework;
}
}
单机安装:
# 解压
tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz
mv apache-zookeeper-3.5.7-bin zookeeper-3.5.7
# 数据目录
cd zookeeper-3.5.7/
mkdir data
java
# 改配置
cd conf/
touch zoo.cfg
cp zoo_sample.cfg zoo.cfg
y
vim zoo.cfg
java
# 进入/bin 启动服务
sh zkServer.sh start
jps
# 进入/bin 启动客户端
sh zkCli.sh
# 退出
quit
java
# 补充:
# 查看状态
sh zkServer.sh status
# 停止服务
sh zkServer.sh stop