[SpringCloud-Zookeeper] 通過Zookeeper的API註冊微服務到Zookeeper -- 第一篇 初探
阿新 • • 發佈:2018-12-28
一.註冊到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);
}
}