springboot整合zookeeper


在springboot中所有的整合都是以bean的形式注入對象,從數據庫coon、redis conn、再到整合的zookeeper,依然是依照bean注入連接對象,通過zookeeper api對zookeeper中node 數據進行增刪改查等操作,從而實現配置同步。這篇文章只是初步使用web服務,在服務啟動時注冊服務,並將配置文件內容寫入zookeeper,通過api接口獲取配置內容。至於多節點配置文件同步一致性,則是以后需要深入研究的主題。

在zookeeper_caesar創建兩個模塊,core和client,core中存放zookeeper連接和相關操作方法,client是正常的web服務。在springboot分層思想中core相當於DAO層,進行zookeeper操作,在client的service層和controller層進行調用和處理。

其中client依賴core模塊,在其pom.xml中添加core模塊信息,其后在client中添加spring模塊spring-boot-starter-web(spring對servlet封裝的模塊和嵌入式tomcat)

        <dependency>
            <groupId>com.soft.caesar</groupId>
            <artifactId>core</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

1.client分析

 

在RegistryConfig.java中創建需要的bean  serviceRegistry 即zookeeper連接對象 zk = new ZooKeeper(zkServers,SESSION_TIMEOUT,this)

在TestController.java中調用serviceRestry即core中定義操作getValue,獲取zookeeper中數據

在WebListener.java中監聽web服務啟動,啟動時將服務存入zookeeper

ClientApplication.py 啟動服務主函數

2.core分析

@Component
public class ServiceRegistryImpl implements ServiceRegistry,Watcher {

    private static CountDownLatch latch = new CountDownLatch(1); # 多線程時,等待,直到一個線程時,在latch被喚醒
    private ZooKeeper zk;
    private static final int SESSION_TIMEOUT=5000;
    private static final String REGISTRY_PATH = "/registry";

    public ServiceRegistryImpl() {
    }

    public ServiceRegistryImpl(String zkServers) {
        try {
            zk = new ZooKeeper(zkServers,SESSION_TIMEOUT,this);
            latch.await();# latch等待喚醒
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void register(String serviceName, String serviceAddress) {
        try {
            String registryPath = REGISTRY_PATH;
            if (zk.exists(registryPath, false) == null) {
                zk.create(registryPath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); #持久化創建/registry node
            }
            //創建服務節點(持久節點)
            String servicePath = registryPath + "/" + serviceName;
            if (zk.exists(servicePath, false) == null) {
                zk.create(servicePath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
            //創建地址節點
            String addressPath = servicePath + "/address-"; # 此處節點是瞬態的節點,當服務斷開zookeeper連接時,節點消失,重新連接時,address- 以序列添加末尾序列值。
這種序列方法可以判斷注冊服務的主被,先注冊的數字小,后注冊的數字大,每次從主上同步數據到被。在服務異常時,節點自動消失,可以探測服務狀態 String addressNode = zk.create(addressPath, serviceAddress.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); } catch (Exception e){ e.printStackTrace(); } } @Override public void process(WatchedEvent watchedEvent) { if (watchedEvent.getState() == Event.KeeperState.SyncConnected) latch.countDown(); }

驗證

啟動zookeeper,啟動以上web服務

java客戶端登錄zookeeper,查詢注冊服務的注冊信息

調用接口查詢zookeeper數據

 以上是關於zookeeper的初步探索,可以參考https://github.com/CaesarLinsa/zookeeper_caesar,在version1.0分支中去掉core模塊,添加到service層中,添加對zookeeper操作接口,實現在接口修改zookeeper同時,配置文件發生變更。當然如此需要每個服務的守護進程中存在類似socket通信,在server端發生變化時,在watch中向守護進程中發送相關命令,促使配置變更,服務啟動或者不啟動加載配置。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM