一 整合
由于本人的码云太多太乱了, 于是决定一个一个的整合到一个 springboot 项目里面.
附上自己的 github 项目地址 https://github.com/247292980/spring-boot
附上汇总博文地址 https://www.cnblogs.com/ydymz/p/9391653.html
以整合功能
spring-boot,FusionChart,thymeleaf,vue,ShardingJdbc,mybatis-generator, 微信分享授权, drools,spring-security,spring-jpa,webjars,Aspect,drools-drt,rabbitmq
这次就来整合下简单的 zookeeper 搭建
二 安装
这玩意最坑的地方在于, 和 mq 一样, 百度第一的安装教程缺了一部分.
1. 先安装 java 并配置环境变量. 直接百度, 进官网下载, 还是程序员最喜欢的解压安装, 赞!
2. 将安装目录下的 conf 文件夹下的 zoo_sample.cfg 复制一份并命名为 zoo.cfg, 如下图
3. 修改一下配置, 主要是 dataDir 和 dataDirLog, 并且要创建相应的文件夹
配置文件简单解析
1,tickTime: 这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔, 也就是每个 tickTime 时间就会发送一个心跳.
2,dataDir: 顾名思义就是 Zookeeper 保存数据的目录, 默认情况下, Zookeeper 将写数据的日志文件也保存在这个目录里.
3,dataLogDir: 顾名思义就是 Zookeeper 保存日志文件的目录
4,clientPort: 这个端口就是客户端连接 Zookeeper 服务器的端口, Zookeeper 会监听这个端口, 接受客户端的访问请求.
4. 进入到 bin 目录, 并且启动 zkServer.cmd
zkServer.cmd
可以通过以下代码检验有没有成功启动, 成功后有一个 QuorumPeerMain 的进程
jps -l -v
5. 启动一个 zkCli
zkCli 127.0.0.1:2181
6. 具体的 cli 可以去 w3c 里面了解, 建议都试一次 https://www.w3cschool.cn/zookeeper/zookeeper_api.html
建议 zkCli 里面, 跑一下这些命令, 否则普通 demo 的 java 代码里面就什么都没有了
- create /FirstZnode FirstZnode1
- create /SecondZnode SecondZnode2
- create /ThirdZnode ThirdZnode3
三 代码
代码有点多, 我只贴集群监听 demo 和普通 demo, 基本上实际使用的都是集群监听 demo, 而普通 demo 是给大家一个过渡的阶段.
要是看完普通还看不懂集群监听, 可以 github 把我的代码拷下来, 里面有个中间态, 监听 demo.
普通 demo, 很简单获取根目录下的全部 children
- public class ZkDemo {
- public static void main(String[] args) throws IOException {
- String hostPort = "localhost:2181";
- List<String> zooChildren = new ArrayList<String>();
- ZooKeeper zk = new ZooKeeper(hostPort, 2000, null);
- if (zk != null) {
- try {
- String zpath = "/";
- zooChildren = zk.getChildren(zpath, false);
- System.out.println("Znodes of'/':");
- for (String child : zooChildren) {
- System.out.println(child);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
集群监听 demo.ClusterMonitor, 写成线程是让他当个服务器, 小白如果看到 idea 提示红色报警有点慌的话, 可以看看文件名字有没有红色波浪线, 没有即说明代码正常
- public class ClusterMonitor implements Runnable {
- private static String membershipRoot = "/Members";
- private final Watcher connectionWatcher;
- private final Watcher childrenWatcher;
- private ZooKeeper zk;
- boolean alive = true;
- public ClusterMonitor(String HostPort) throws IOException, InterruptedException, KeeperException {
- connectionWatcher = new Watcher() {
- @Override
- public void process(WatchedEvent event) {
- if (event.getType() == Watcher.Event.EventType.None && event.getState() == Watcher.Event.KeeperState.SyncConnected) {
- System.out.printf("\nEvent Received: %s", event.toString());
- }
- }
- };
- childrenWatcher = new Watcher() {
- @Override
- public void process(WatchedEvent event) {
- System.out.printf("\nEvent Received: %s", event.toString());
- if (event.getType() == Event.EventType.NodeChildrenChanged) {
- try {
- //Get current list of child znode,
- //reset the watch
- List<String> children = zk.getChildren(membershipRoot, this);
- wall("!!!Cluster Membership Change!!!");
- wall("Members:" + children);
- } catch (KeeperException e) {
- throw new RuntimeException(e);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- alive = false;
- throw new RuntimeException(e);
- }
- }
- }
- };
- zk = new ZooKeeper(HostPort, 2000, connectionWatcher);
- // Ensure the parent znode exists
- if (zk.exists(membershipRoot, false) == null) {
- zk.create(membershipRoot, "ClusterMonitorRoot".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- }
- // Set a watch on the parent znode
- List<String> children = zk.getChildren(membershipRoot, childrenWatcher);
- System.err.println("Members:" + children);
- }
- public synchronized void close() {
- try {
- zk.close();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- public void wall(String message) {
- System.out.printf("\nMESSAGE: %s", message);
- }
- @Override
- public void run() {
- try {
- synchronized (this) {
- while (alive) {
- wait();
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- Thread.currentThread().interrupt();
- } finally {
- this.close();
- }
- }
- public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
- String hostPort = "localhost:2181";
- new ClusterMonitor(hostPort).run();
- }
- }
集群监听 demo.ClusterClient, 这个可能需要你多开几个 java 线程跑, idea 改一下启动参数就好了, 然后在服务器里面对比才比较明显
命令行启动 java 线程的代码
- java -cp $CLASSPATH ClusterMonitor
- public class ClusterClient implements Watcher, Runnable {
- private static String membershipRoot = "/Members";
- ZooKeeper zk;
- public ClusterClient(String hostPort, Long pid) {
- String processId = pid.toString();
- try {
- zk = new ZooKeeper(hostPort, 2000, this);
- if (zk != null) {
- zk.create(membershipRoot + '/' + processId, processId.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public synchronized void close() {
- try {
- zk.close();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void process(WatchedEvent event) {
- System.out.printf("\nEvent Received: %s", event.toString());
- }
- @Override
- public void run() {
- try {
- synchronized (this) {
- while (true) {
- wait();
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- Thread.currentThread().interrupt();
- } finally {
- this.close();
- }
- }
- public static void main(String[] args) {
- String hostPort = "localhost:2181";
- //Get the process id
- String name = ManagementFactory.getRuntimeMXBean().getName();
- int index = name.indexOf('@');
- Long processId = Long.parseLong(name.substring(0, index));
- new ClusterClient(hostPort, processId).run();
- }
- }
四 总结
1. 因为基本是和 rabbitmq 一起写的博文, 我难免会把他们做一番对比, zk 和 mq 的安装比起来, 明显 zk 简单多了. 或许原因是 mq 是用 erlang 写的?
2.zk 的生态圈很好, 毕竟是 Apache 大厂出品, 以上的代码, 都是直接看 Apache zookeeper 的官网 java 版的 api 写的, 比 rabbitmq 不是好的一点半点, 例如 mq 包的报错日志问题...
来源: https://www.cnblogs.com/ydymz/p/9626653.html