使用zk官方包和Curator连接zk集群并测试当服务端挂掉一个端口之后的重连

1、使用zk官方包连接zk集群

1.1、连接服务端的基类代码

public class ClusterBase {

    private final static  String CLUSTER_CONNECT_STR="192.168.231.131:2181,192.168.231.131:2182,192.168.231.131:2183,192.168.231.131:2184";

    private static final  int SESSION_TIMEOUT=30 * 1000;

    private static ZooKeeper zooKeeper =null;

    private static CountDownLatch countDownLatch = new CountDownLatch(1);

    private Watcher watcher =new Watcher() {
        @Override
        public void process(WatchedEvent event) {
            if (event.getState() == Event.KeeperState.SyncConnected
                    && event.getType()== Event.EventType.None){
                countDownLatch.countDown();
                System.out.println("连接建立");
            }
        }
    };

    @Before
    public void init(){
        try {
            System.out.println(" start to connect to zookeeper server: " + getConnectStr());
            zooKeeper=new ZooKeeper(getConnectStr(), getSessionTimeout(), watcher);
            System.out.println(" 连接中...");
            countDownLatch.await();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static ZooKeeper getZooKeeper() {
        return zooKeeper;
    }

    @After
    public void   test(){
        try {
            TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    protected String getConnectStr(){
        return CLUSTER_CONNECT_STR;
    }

    protected int getSessionTimeout() {
        return SESSION_TIMEOUT;
    }
}

1.2、连接服务操作代码

zk官方包去连接zk集群的话,如果zk集群向外提供的端口挂掉了,我们客户端重连时是需要我们自己捕获异常的,代码如下所示:

@Slf4j
public class ClusterOperations extends ClusterBase {

    @Test
    public void testReconnect() throws InterruptedException {
        while (true){
            try {
                Stat stat = new Stat();
                byte[] data = getZooKeeper().getData("/zookeeper", false, stat);
                System.out.println("get data :" + new String(data));

                TimeUnit.SECONDS.sleep(5);
            }catch (Exception e){
                e.printStackTrace();
                System.out.println(" 开始重连......");

                while (true){
                    System.out.println("zookeeper status :" + getZooKeeper().getState().name());
                    if (getZooKeeper().getState().isConnected()) {
                        break;
                    }
                    TimeUnit.SECONDS.sleep(3);
                }
            }
        }
    }

1.3、当我们挂掉向外提供的服务时,验证重连

1、首先我们运行操作类,如果出现5s获取一次就是正常
如下图所示:

在这里插入图片描述


2、使用 netstat -ntp 命令查看当前集群向外提供的端口,如下图红框中所示:

在这里插入图片描述


3、由此可见,集群向外提供的是2183端口,所以当我们停掉2183端口的服务后,观察集群是否能选举成功。
当我们停掉2183端口后,发现控制台重新连接了一下,然后又正常了,如下图所示:

在这里插入图片描述


4、如果上述一切正常,我们再次使用 netstat -ntp 命令查看当前集群向外提供的端口,如果集群有向外提供另一个端口,如下图所示,则代表集群在挂掉一个节点之后,选举成功,并使得客户端重新连接。

在这里插入图片描述

2、使用Curator连接zk集群

2.1、连接服务端的基类代码

我们也可以使用Curator的代码来测试,其它的步骤都一样,代码如下,

public  class CuratorClusterBase {

    private final static  String CLUSTER_CONNECT_STR="192.168.231.131:2181,192.168.231.131:2182,192.168.231.131:2183,192.168.231.131:2184";

    private static final int sessionTimeoutMs = 60*1000;
    private static final int connectionTimeoutMs = 5000;
    private static CuratorFramework curatorFramework;

    @Before
    public void init() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(5000, 30);
        curatorFramework = CuratorFrameworkFactory.builder().connectString(getConnectStr())
                .retryPolicy(retryPolicy)
                .sessionTimeoutMs(sessionTimeoutMs)
                .connectionTimeoutMs(connectionTimeoutMs)
                .canBeReadOnly(true)
                .build();
        curatorFramework.getConnectionStateListenable().addListener((client, newState) -> {
            if (newState == ConnectionState.CONNECTED) {
                System.out.println("连接成功!");
            }

        });
        System.out.println("连接中......");
        curatorFramework.start();
    }

    public void createIfNeed(String path) throws Exception {
        Stat stat = curatorFramework.checkExists().forPath(path);
        if (stat==null){
            String s = curatorFramework.create().forPath(path);
        }
    }

    public static CuratorFramework getCuratorFramework() {
        return curatorFramework;
    }

    @After
    public void   test(){
        try {
            TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    protected   String getConnectStr(){
        return CLUSTER_CONNECT_STR;
    }
}

2.2、连接服务操作代码

public class CuratorClusterBaseOperations extends CuratorClusterBase {
    @Test
    public void testCluster() throws Exception {
        CuratorFramework curatorFramework = getCuratorFramework();
        String pathWithParent = "/zookeeper";
        byte[] bytes = curatorFramework.getData().forPath(pathWithParent);
        System.out.println(new String(bytes));
        while (true) {

            try {
                byte[] bytes2 = curatorFramework.getData().forPath(pathWithParent);
                System.out.println("get data:" + new String(bytes2));

                TimeUnit.SECONDS.sleep(5);
            } catch (Exception e) {
                e.printStackTrace();
                testCluster();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 你可以通过以下步骤使用Java结合Curator实时监听每个服务器的实际状态: 1. 首先,建立一个Curator客户端连接ZooKeeper。你可以使用以下代码建立连接: ``` CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, new RetryNTimes(retryCount, sleepTime)); client.start(); ``` 这里,`zookeeperConnectionString`是ZooKeeper服务器的连接字符串,`retryCount`和`sleepTime`是Curator重试连接的次数和时间间隔。 2. 接下来,你需要在ZooKeeper上创建一个节点,用于存储每个服务器的状态。你可以使用以下代码创建一个节点: ``` String path = "/servers/server1"; // 这里的“server1”是你要监听的服务器名称 client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path); ``` 这里,`CreateMode.EPHEMERAL`表示创建一个临时节点,当与ZooKeeper连接客户端断开连接时,该节点将被删除。 3. 接下来,在每个服务器上创建一个节点,用于存储服务器的状态。你可以使用以下代码创建一个节点: ``` String path = "/servers/server1/status"; // 这里的“server1”是你要监听的服务器名称 client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path); ``` 4. 然后,你需要在每个服务器上运行一个线程,定期更新服务器状态。你可以使用以下代码实现: ``` while (true) { String path = "/servers/server1/status"; // 这里的“server1”是你要监听的服务器名称 byte[] data = getStatus(); // 获取服务器状态的方法 client.setData().forPath(path, data); Thread.sleep(updateInterval); // 更新时间间隔 } ``` 这里,`getStatus()`方法返回服务器状态的字节数组,`updateInterval`是更新时间间隔,单位为毫秒。 5. 最后,你需要使用Curator的`PathChildrenCache`类监听每个服务器的状态节点。你可以使用以下代码实现: ``` String path = "/servers/server1"; // 这里的“server1”是你要监听的服务器名称 PathChildrenCache cache = new PathChildrenCache(client, path, true); cache.getListenable().addListener(new PathChildrenCacheListener() { @Override public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception { switch (event.getType()) { case CHILD_ADDED: // 处理服务器状态节点添加事件 break; case CHILD_UPDATED: // 处理服务器状态节点更新事件 break; case CHILD_REMOVED: // 处理服务器状态节点删除事件 break; } } }); cache.start(); ``` 这里,`PathChildrenCache`类可以监听一个节点下的子节点的创建、更新和删除事件。你可以在`childEvent()`方法中处理这些事件,以实时获取每个服务器的实际状态。 以上就是使用Java结合Curator实时监听每个服务器的实际状态的步骤。 ### 回答2: 使用Java结合Curator可以实时监听每个服务器的实际状态。首先,我们需要创建一个Curator客户端连接ZooKeeper集群。然后,使用Curator的PathChildrenCache来监听每个服务器的节点。 1. 创建Curator客户端连接ZooKeeper集群。 ```java CuratorFramework client = CuratorFrameworkFactory.newClient("zookeeperhost:port", new RetryNTimes(5, 1000)); client.start(); ``` 2. 使用PathChildrenCache监听每个服务器的节点变化。 ```java PathChildrenCache cache = new PathChildrenCache(client, "/servers", true); cache.start(); // 添加节点变化的监听器 cache.getListenable().addListener((framework, event) -> { if (event.getType() == Type.CHILD_ADDED) { // 服务器上线,连接到对应的Mysql数据库 String serverNodePath = event.getData().getPath(); String serverName = serverNodePath.substring(serverNodePath.lastIndexOf('/') + 1); String mysqlHost = getMysqlHost(serverName); connectToMysql(mysqlHost); } else if (event.getType() == Type.CHILD_REMOVED) { // 服务器下线,关闭对应的Mysql连接 String serverNodePath = event.getData().getPath(); String serverName = serverNodePath.substring(serverNodePath.lastIndexOf('/') + 1); String mysqlHost = getMysqlHost(serverName); closeMysqlConnection(mysqlHost); } }); ``` 3. 在监听器中,可以根据节点变化的类型进行相应的处理。当服务器上线时,获取服务器名称,并根据服务器名称找到对应的Mysql主机地址,连接到Mysql数据库。当服务器下线时,根据服务器名称找到对应的Mysql主机地址,并关闭对应的Mysql连接。 以上是使用Java结合Curator实时监听每个服务器的实际状态的思路和代码示例。注意,示例中需要根据实际情况调整节点路径和数据库连接的逻辑。 ### 回答3: 要使用JAVA结合Curator实时监听每个服务器的实际状态,可以按照以下步骤进行操作: 1. 首先,引入Curator的依赖。在项目的pom.xml文件中添加Curator的相关依赖,如curator-framework和curator-recipes。 2. 创建一个Curator客户端实例。使用Curator提供的CuratorFrameworkFactory类创建一个Curator客户端实例,并设置连接参数,如连接字符串、连接超时时间等。 3. 使用Curator的PathChildrenCache监听每个服务器的状态变化。通过Curator的PathChildrenCache可以对指定路径下的子节点进行监听,即监听每个服务器的状态变化。可以使用CuratorFramework的create方法创建一个PathChildrenCache实例,并指定要监听的路径。 4. 添加PathChildrenCache的监听器。为每个PathChildrenCache实例添加一个监听器,实现监听器的PathChildrenCacheListener接口,并重写相应的方法,如childEvent方法,以处理节点变化的事件。 5. 开启PathChildrenCache的监听器。通过调用PathChildrenCache的start方法,开启该监听器。 6. 获取每个服务器的实际状态。在监听器的相应方法中,可以获取到节点变化的相关信息。根据需要,可以获取节点的路径、节点的数据等信息,来获取每个服务器的实际状态。 7. 根据需求处理每个服务器的状态变化。根据获取到的每个服务器的实际状态,可以进行相应的处理操作,如更新数据库或发送通知等。 通过以上步骤,就可以使用JAVA结合Curator实时监听每个服务器的实际状态。使用Curator可以简化与ZooKeeper的交互操作,并提供了一些方便的监听功能,能够很好地满足实时监听服务器状态的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值