Zookeeper实现服务注册与发现
在分布式架构中,系统经常被暴漏为服务供其他系统调用,为使系统间能够相互通信,需要有一个协调系统来管理这些服务,这就是服务注册与服务发现,这个协调者也被称之为注册中心。
下面基于zookeeper来实现一个简单的服务注册与发现功能
通过Maven引入需要的jar包
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
创建服务注册类
package com.wrxiang.zk.util;
import org.I0Itec.zkclient.ZkClient;
public class ZkServiceRegistry {
private ZkClient zkClient;
public void registry(String serviceName, String serviceAddress){
zkClient = new ZkClient("127.0.0.1");
//创建registry节点
String registryAddress = "/services";
if(!zkClient.exists(registryAddress)){
zkClient.createPersistent(registryAddress);
System.out.println("创建服务注册节点");
}
//创建service节点
String servicePath = registryAddress + "/" + serviceName;
if(!zkClient.exists(servicePath)){
zkClient.createPersistent(servicePath);
System.out.println("创建服务节点,服务名:" + serviceName);
}
//创建address节点(临时)
String addressPath = servicePath + "/address-";
String addressNode = zkClient.createEphemeralSequential(addressPath, serviceAddress);
System.out.println("创建服务地址节点:" + addressNode);
}
}
创建服务发现类
package com.wrxiang.zk.util;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;
public class ZkServiceDiscovery {
private final List<String> addressCache = new CopyOnWriteArrayList<>();
private ZkClient zkClient;
public String discovery(String serviceName){
zkClient= new ZkClient("127.0.0.1");
String servicePath = "/services/" + serviceName;
if(!zkClient.exists(servicePath)){
throw new RuntimeException("未发现服务节点:" + servicePath);
}
String address;
//先从本地系统缓存中取
if(addressCache.size() == 1){
address = addressCache.get(0);
}else if(addressCache.size() > 1){
address = addressCache.get(ThreadLocalRandom.current().nextInt(addressCache.size()));
}else{
//从ZK注册中心中取
List<String> addressList = zkClient.getChildren(servicePath);
addressCache.clear();
addressCache.addAll(addressList);
zkClient.subscribeChildChanges(servicePath,(parentPath,currentChilds)->{
System.out.println("监听服务节点发生变化:" + parentPath);
addressCache.clear();
addressCache.addAll(currentChilds);
});
if(CollectionUtils.isEmpty(addressCache)){
throw new RuntimeException("未发现有效的服务节点");
}
if(addressList.size() == 1){
address = addressList.get(0);
}else {
address = addressList.get(ThreadLocalRandom.current().nextInt(addressList.size()));
}
}
//获取实际地址
String addressPath = servicePath + "/" + address;
String hostAndPort = zkClient.readData(addressPath);
System.out.println("获取到实际访问地址:" + hostAndPort);
zkClient.close();
return hostAndPort;
}
}
创建测试类
package com.wrxiang.zk.util;
public class ZookeeperApplicationTest {
public static void main(String[] args) throws InterruptedException {
String serviceName = "test.com";
ZkServiceRegistry registry = new ZkServiceRegistry();
registry.registry(serviceName,"192.168.3.1:8080");
Thread.sleep(1000);
ZkServiceDiscovery zkServiceDiscovery = new ZkServiceDiscovery();
zkServiceDiscovery.discovery(serviceName);
}
}
启动zookeeper,然后运行测试类,可以发现服务能够正常注册到zookeeper,也能够被正常的发现。
本文作者:~鲨鱼辣椒~
本文链接:https://www.cnblogs.com/wrxiang/p/15145389.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

浙公网安备 33010602011771号