Zookeeper實現服務註冊與發現
阿新 • • 發佈:2021-08-16
在分散式架構中,系統經常被暴漏為服務供其他系統呼叫,為使系統間能夠相互通訊,需要有一個協調系統來管理這些服務,這就是服務註冊與服務發現,這個協調者也被稱之為註冊中心。
下面基於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