Zookeeper实现分布式应用的(主节点HA)及客户端动态更新主节点状态

某分布式系统中,主节点可以有多台,可以动态上下线
任意一台客户端都能实时感知到主节点服务器的上下线
服务端逻辑:

服务端启动时在zookeeper集群中 /services节点写入一个临时节点,该临时节点内容为该节点的名称。当服务端下线或者宕机时zookeeper会将该节点删除

客户端逻辑

客户端启动时会查找/services 下所有节点 并将节点名输出,当节点变化时,会重新查找所有节点,并将节点名输出

import org.apache.zookeeper.CreateMode
import org.apache.zookeeper.Watcher
import org.apache.zookeeper.ZooDefs
import org.apache.zookeeper.ZooKeeper

/**
 * 服务端
 */
object DistributedServer {
    //逗号分隔主机:端口对,每个对应一个ZooKeeper 主机名/IP 与配置文件相同
    private val CONNECT_STRING: String = "192.168.84.132:2181,192.168.84.133:2181,192.168.84.134:2181"
    //会话超时(毫秒)
    private val SESSION_TIMEOUT: Int = 2000
    //获取zooKeeper客户端连接
    private val zooKeeper: ZooKeeper by lazy {
        ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, Watcher { event ->
            //Watch回调
            println("${event?.type}-->${event?.path}")
            //创建监听节点变化,非数据
            zooKeeper.getChildren("/", true)
        })
    }

    @JvmStatic
    fun main(args: Array<String>) {
        val serviceName = args[0]
        zooKeeper.create("/services/service", serviceName.toByteArray(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL)
        println("serviceName --> $serviceName create")
        println("$serviceName start working.....")
        Thread.sleep(Long.MAX_VALUE)
    }
}

import org.apache.zookeeper.Watcher
import org.apache.zookeeper.ZooKeeper
import org.apache.zookeeper.data.Stat

/**
 * 客户端
 */
object DistributedClient {

    //逗号分隔主机:端口对,每个对应一个ZooKeeper 主机名/IP 与配置文件相同
    private val CONNECT_STRING: String = "192.168.84.132:2181,192.168.84.133:2181,192.168.84.134:2181"
    //会话超时(毫秒)
    private val SESSION_TIMEOUT: Int = 2000
    private val zooKeeper: ZooKeeper by lazy {
        ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, Watcher { event ->
            println("${event?.type}-->${event?.path}")
            getServiceList()
        })

    }
    //Volatile
    @Volatile private lateinit var services: ArrayList<String>

    @JvmStatic
    fun main(args: Array<String>) {
        getServiceList()
        println("client start working.....")
        Thread.sleep(Long.MAX_VALUE)
    }

    private fun getServiceList() {
        //每次/services子节点变化都会调用watch
        val serviceList = zooKeeper.getChildren("/services", true)
        //设置临时集合存储所有service 信息
        val tempList = arrayListOf<String>()
        serviceList
                //取每个service的信息并存入临时集合
                .map { zooKeeper.getData("/services/" + it, false, Stat())}
                .mapTo(tempList) { String(it) }
        services = tempList
        println(services)
    }
}

服务端

service

客户端

client

服务端上下线 客户端更新
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值