1. 程式人生 > >[SpringCloud-Zookeeper] 通過Zookeeper的API註冊微服務到Zookeeper -- 第一篇 初探

[SpringCloud-Zookeeper] 通過Zookeeper的API註冊微服務到Zookeeper -- 第一篇 初探

一.註冊到ZK

    springboot工程通過引入zk的依賴,通過註解註冊到zk,這個網上資料很多,就不多囉嗦了,這裡主要給出,通過api註冊到zk,什麼場景會用到呢?比如環境中有一些springboot工程,也有非springboot工程,那麼對於springboot工程直接通過註解註冊,通過Feign呼叫其他微服務,非springboot工程通過api註解,其他服務通過服務名稱呼叫即可;

二.springboot工程註冊

    sprinboot工程主需要引入相關依賴,通過註解即可,這裡一筆帶過:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        <version>1.1.3.RELEASE</version>
    </dependency>
    
    註解:@EnableDiscoveryClient
    

三.普通Java工程

1.這裡我以springboot工程為例,但是不引入第二步中的依賴來實現註冊和服務呼叫

    pom依賴
    <dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.11</version>
			<type>pom</type>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
		<dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.10</version>
	</dependency>

2.環境簡介:

    這裡我先註冊兩個服務到ZK,一個zkClient,一個provider,這倆個都是標準的springboot工程,整合第二步中的元件註冊,zkClient會在介面中呼叫provider和後面要通過api註冊的微服務zkServices,並且有個介面會返回所有的例項,簡單程式碼如下:
    //使用Feign呼叫微服務
    @RequestMapping("/")
        public String test() {
	        //呼叫provider服務
            String str1 = providerClientI.callProviderTwo();
            //呼叫zkServices服務
            String str2 = zkClientI.callProviderOne();
            return str1 + "-------" + str;
    }
    
    //獲取所有zk的微服務例項
    @GetMapping("/allServices")
    public List<List<ServiceInstance>> allServiceUrl() {
        List<String> list = discoveryClient.getServices();
        List<List<ServiceInstance>> serviceInstance = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (String serviceId : list) {
                serviceInstance.add(discoveryClient.getInstances(serviceId));
            }
        }
        return serviceInstance;
    }
    

3.ZK檢視:

    進入到zk的目錄下,使用命令./zkCli.sh -server 192.168.xx.xx:2181接入zookeeper,然後使用ls / 檢視所有的節點,然後使用ls /services檢視services下的節點,註冊的服務預設在services節點下,此時可以看到provider,和zkClient,檢視provider和zkClient下面發現下面有一個節點,貌似是以UUID命名的,然後使用get命令檢視下面的節點內的資料內容,如下:

這裡寫圖片描述

然後我們大概明白了,原來一個微服務例項註冊到zk,就是在節點裡面放了這些資料,下面開始我們通過API註冊的工作

4.API註冊:

    我先來一段很簡單的程式碼,全部是寫死的,後面測試我們的方法可行之後,我們再對程式碼進行優雅的改造,該封裝的封裝,該寫成配置的就配置化,先驗證後完善,這裡的regeister方法是核心方法,裡面通過Zookeeper類的create方法向伺服器建立節點並把資料寫入節點,實際上寫入的就是服務的註冊資訊,寫入之後,其他的節點才能發現本節點,繼而才能呼叫它;
@Override
    public void register(String serviceName, String serviceAddress) {
        String registryPath = REGISTRY_PATH;
        try {
            zk.create("/services/zkServices", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            String  uuid = "95b4f91c-96b9-4aa6-ab61-935a7f8be599";
            String data = "{\"name\":\"zkService\",\"id\":\"95b4f91c-96b9-4aa6-ab61-935a7f8be599\",\"address\":\"192.168.6.164\",\"port\":9505,\"sslPort\":null,\"payload\":{\"@class\":\"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance\",\"id\":\"zkService:9505\",\"name\":\"zkService\",\"metadata\":{\"instance_status\":\"UP\"}},\"registrationTimeUTC\":1534763883884,\"serviceType\":\"DYNAMIC\",\"uriSpec\":{\"parts\":[{\"value\":\"scheme\",\"variable\":true},{\"value\":\"://\",\"variable\":false},{\"value\":\"address\",\"variable\":true},{\"value\":\":\",\"variable\":false},{\"value\":\"port\",\"variable\":true}]}}";
            zk.create("/services/zkServices/" + uuid, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (Exception e) {
            logger.error("create node failure", e);
        }
    }
    這段程式碼簡單粗暴,就是直接create建立/services/zkServices節點,然後再create往裡面放入資料,資料就是從provider服務裡面拷貝過來的,就是個json,我把相關的地址,服務名稱啥的改了下,然後啟動工程,之後檢查zk,果然建立了節點,get命令檢視資料也和建立的一致,然後在訪問zkClient服務的上面的兩個介面,都成功了,一個正確的返回了zkServices和provider的響應字串,另一個介面正確顯示出了三個服務的資訊,包括zkClient,provider,zkServices,這說明通過api註冊一個服務成功了;

四.普通Java工程

    驗證方法正確之後,我們對程式碼進行一下簡單的封裝,相關引數配置化。下一篇部落格我給出封裝後的程式碼和相關引數含義的簡單解釋。