前置:
集群安装虚拟机CentOS-7-x86_64-Minimal-2009
IP:192.168.18.11、192.168.18.12、192.168.18.13
安装位置:/usr/local/
1、需要安装JDK8
见CENTOS7 JDK安装_du251254082的博客-CSDN博客
2、下载zookeeper二进制安装包
https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
3、将解压后的二进制文件夹apache-zookeeper-3.7.1-bin放入安装目录
创建数据目录:apache-zookeeper-3.7.1-bin/data
创建日志目录:apache-zookeeper-3.7.1-bin/logs
集群中每个zk服务定义一个唯一{id},如此处:
192.168.18.11 11
192.168.18.12 12
192.168.18.13 13
在apache-zookeeper-3.7.1-bin/data中创建myid文件,将#{id}写入myid中
如192.168.18.11:echo "11" > apache-zookeeper-3.7.1-bin/data/myid
4、配置相关
复制apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg 为apache-zookeeper-3.7.1-bin/conf/zoo.cfg
修改配置:
tickTime=2000
initLimit=10
syncLimit=5
clientPort=2181
#与上面日志目录对应
dataLogDir=/opt/apps/zookeeper-3.7.1/logs
#与上面数据目录对应
dataDir=/opt/apps/zookeeper-3.7.1/data
autopurge.snapRetainCount=500
autopurge.purgeInterval=24
#server.{id}={ip}:{port1}:{port2}
server.11=192.168.18.11:2888:3888
server.12=192.168.18.12:2888:3888
server.13=192.168.18.13:2888:3888
说明:server.{id}={ip}:{port1}:{port2}中
{id} 与3中{id}对应
{ip} 本机ip改为0.0.0.0
5、开放端口:
firewall-cmd --zone=public --add-port=2181/tcp --permanent
firewall-cmd --zone=public --add-port=2888/tcp --permanent
firewall-cmd --zone=public --add-port=3888/tcp --permanent
systemctl reload firewalld
6、命令:
启动:/usr/local/apache-zookeeper-3.7.1-bin/bin/zkServer.sh stop&&/usr/local/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start && /usr/local/apache-zookeeper-3.7.1-bin/bin/zkServer.sh status
查看日志:/usr/local/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start-foreground
7、开机启动
服务:rc-local.service配置文件/etc/rc.d/rc.local中加入启动命令
touch /var/lock/subsys/local
export JAVA_HOME=/usr/local/jdk1.8.0_371
#/usr/local/apache-zookeeper-3.7.1-bin/startUp.sh
/usr/local/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
确认服务是否启动,是否开机启动: systemctl status rc-local.service
8、springboot集成
pom依赖:
<!--Zookeeper-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.0</version>
</dependency>
<!--Curator-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.1</version>
</dependency>
yaml配置:
curator:
#重试retryCount次,当会话超时出现后,curator会每间隔elapsedTimeMs毫秒时间重试一次,共重试retryCount次。
retryCount: 5
elapsedTimeMs: 5000
#服务器信息
connectString: 192.168.18.11:2182,192.168.18.12:2182,192.168.18.13:2182
#会话超时时间设置
sessionTimeoutMs: 60000
#连接超时时间
connectionTimeoutMs: 5000
客户端初始化:
@Component
public class ZkClientFactoryBean implements FactoryBean<CuratorFramework> {
@Value("${curator.connectString}")
private String connectString;
@Value("${curator.retryCount:3}")
private int maxRetries;
@Value("${curator.baseSleepTimeMs:1000}")
private int baseSleepTimeMs;
private CuratorFramework curatorClient;
@PostConstruct
public void init() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries);
curatorClient = CuratorFrameworkFactory.builder()
.connectString(connectString)
.retryPolicy(retryPolicy)
.build();
curatorClient.start();
}
@Override
public CuratorFramework getObject() throws Exception {
return curatorClient;
}
@Override
public Class<?> getObjectType() {
return CuratorFramework.class;
}
}
基本使用:
@Component
public class ZkListener {
@Resource
private CuratorFramework curatorClient;
@PostConstruct
public void init() throws Exception {
String path = "/zk";
//监听当前节点变化,不监听子节点变化
NodeCache nodeCache = new NodeCache(curatorClient, path);
nodeCache.start();
nodeCache.getListenable().addListener(() -> {
String nodePath = nodeCache.getCurrentData().getPath();
String data = new String(nodeCache.getCurrentData().getData());
System.out.println("nodeChanged,nodePath:" + nodePath + " data:" + data);
});
//监听子节点变化,不监听当前节点变化
PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorClient, path, true);
pathChildrenCache.start();
pathChildrenCache.getListenable().addListener((curatorFramework, event) -> {
String type = event.getType().name();
System.out.println("pathChildrenCache, type:" + type);
Optional.ofNullable(event.getData()).ifPresent(t->{
String nodePath = t.getPath();
String data = new String(t.getData());
System.out.println("pathChildrenCache, nodePath:" + nodePath + " data:" + data + " type:" + type);
});
});
//监听当前节点及其所有子节点变化
TreeCache treeCache = new TreeCache(curatorClient, path);
treeCache.start();
treeCache.getListenable().addListener((curatorFramework, event) -> {
String type = event.getType().name();
System.out.println("treeCache, type:" + type);
Optional.ofNullable(event.getData()).ifPresent(t->{
String nodePath = t.getPath();
String data = new String(t.getData());
System.out.println("treeCache, nodePath:" + nodePath + " data:" + data + " type:" + type);
});
});
}
}