基於Spring Cloud實現服務的發布與調用。而在18年7月份,Eureka2.0宣布停更了,將不再進行開發,所以對於公司技術選型來說,可能會換用其他方案做注冊中心。本章學習便是使用ZooKeeper作為注冊中心。
搭建zookeeper服務,參考【ZooKeeper】ZooKeeper安裝及簡單操作
本章使用的zookeeper版本是 3.6.0
項目架構圖如下:
搭建服務提供者
1、新建一個maven項目(test-springcloud-provider-payment8004)
結構如下:
2、引入依賴,編輯pom文件
1 <!-- spring-cloud 整合 zookeeper --> 2 <dependency> 3 <groupId>org.springframework.cloud</groupId> 4 <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> 5 </dependency>
完整pom文件如下:

1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>test-springcloud</artifactId> 7 <groupId>com.test</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>test-springcloud-provider-payment8004</artifactId> 13 14 <dependencies> 15 16 <!-- spring-cloud 整合 zookeeper --> 17 <dependency> 18 <groupId>org.springframework.cloud</groupId> 19 <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> 20 <!-- 排除自帶的zookeeper jar包 --> 21 <exclusions> 22 <exclusion> 23 <groupId>org.apache.zookeeper</groupId> 24 <artifactId>zookeeper</artifactId> 25 </exclusion> 26 </exclusions> 27 </dependency> 28 29 <!-- zookeeper 引入對應版本的zookeeper --> 30 <dependency> 31 <groupId>org.apache.zookeeper</groupId> 32 <artifactId>zookeeper</artifactId> 33 <version>3.6.0</version> 34 <exclusions> 35 <exclusion> 36 <groupId>org.slf4j</groupId> 37 <artifactId>slf4j-log4j12</artifactId> 38 </exclusion> 39 <exclusion> 40 <groupId>log4j</groupId> 41 <artifactId>log4j</artifactId> 42 </exclusion> 43 </exclusions> 44 </dependency> 45 46 <!-- spring boot --> 47 <dependency> 48 <groupId>org.springframework.boot</groupId> 49 <artifactId>spring-boot-starter-web</artifactId> 50 </dependency> 51 <dependency> 52 <groupId>org.springframework.boot</groupId> 53 <artifactId>spring-boot-starter-actuator</artifactId> 54 </dependency> 55 56 <dependency> 57 <groupId>org.springframework.boot</groupId> 58 <artifactId>spring-boot-devtools</artifactId> 59 <scope>runtime</scope> 60 <optional>true</optional> 61 </dependency> 62 <dependency> 63 <groupId>org.projectlombok</groupId> 64 <artifactId>lombok</artifactId> 65 <optional>true</optional> 66 </dependency> 67 68 <dependency> 69 <groupId>org.springframework.boot</groupId> 70 <artifactId>spring-boot-starter-test</artifactId> 71 <scope>test</scope> 72 </dependency> 73 74 </dependencies> 75 76 <build> 77 <finalName>test-springcloud-provider-payment8004</finalName> 78 </build> 79 80 </project>
需要注意,由於通過spring-cloud-starter-zookeeper-discovery依賴引入的zookeeper jar包,於zookeeper服務器版本不一致導致的,導致項目啟動失敗
報錯:Caused by: org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for /services/xx/xxx
解決:引入對於版本的 zookeeper jar包,本章使用的zookeeper版本是3.6.0,所以引入zookeeper-3.6.0.jar,如下:

1 <!-- spring-cloud 整合 zookeeper --> 2 <dependency> 3 <groupId>org.springframework.cloud</groupId> 4 <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> 5 <!-- 排除自帶的zookeeper jar包 --> 6 <exclusions> 7 <exclusion> 8 <groupId>org.apache.zookeeper</groupId> 9 <artifactId>zookeeper</artifactId> 10 </exclusion> 11 </exclusions> 12 </dependency> 13 14 <!-- zookeeper 引入對應版本的zookeeper --> 15 <dependency> 16 <groupId>org.apache.zookeeper</groupId> 17 <artifactId>zookeeper</artifactId> 18 <version>3.6.0</version> 19 <exclusions> 20 <exclusion> 21 <groupId>org.slf4j</groupId> 22 <artifactId>slf4j-log4j12</artifactId> 23 </exclusion> 24 <exclusion> 25 <groupId>log4j</groupId> 26 <artifactId>log4j</artifactId> 27 </exclusion> 28 </exclusions> 29 </dependency>
3、編輯配置文件application.yml
1 # 端口 2 server: 3 port: 8004 4 5 spring: 6 application: 7 name: cloud-payment-service 8 cloud: 9 zookeeper: 10 # 集群模式用逗號隔開 11 connect-string: 127.0.0.1:2181
4、編寫主啟動類
1 // 啟用服務發現 2 @EnableDiscoveryClient 3 @SpringBootApplication 4 public class PaymentMain8004 { 5 public static void main(String[] args) { 6 SpringApplication.run(PaymentMain8004.class, args); 7 } 8 }
5、編寫Controller
1 @RestController 2 @Slf4j 3 public class PaymentController { 4 5 @Value("${server.port}") 6 private String serverPort; 7 8 @RequestMapping(value = "payment/zk") 9 public String paymentzk(){ 10 return "springcloud with zookeeper:" + serverPort + "\t" + UUID.randomUUID(); 11 } 12 }
6、啟動項目,測試
1)使用地址:http://localhost:8004/payment/zk
2)使用zookeeper客戶端連接到zookeeper服務中,查看節點信息
json格式如下:

1 { 2 "name": "cloud-payment-service", 3 "id": "4f3db6b1-7d3a-4b3e-ac7a-159289573440", 4 "address": "192.168.1.4", 5 "port": 8004, 6 "sslPort": null, 7 "payload": { 8 "@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance", 9 "id": "application-1", 10 "name": "cloud-payment-service", 11 "metadata": {} 12 }, 13 "registrationTimeUTC": 1586166066913, 14 "serviceType": "DYNAMIC", 15 "uriSpec": { 16 "parts": [{ 17 "value": "scheme", 18 "variable": true 19 }, { 20 "value": "://", 21 "variable": false 22 }, { 23 "value": "address", 24 "variable": true 25 }, { 26 "value": ":", 27 "variable": false 28 }, { 29 "value": "port", 30 "variable": true 31 }] 32 } 33 }
7、測試zookeeper的服務節點是臨時節點還是永久節點?
通過關閉應用服務,在zookeeper客戶端中是用命令:ls /services/cloud-payment-service,
查看服務之后存在,然后啟動服務,查看節點ID是否相同
通過測試驗證:zookeeper的服務節點是臨時節點
搭建服務消費者
1、新建一個maven項目(test-springcloud-order7999)
項目結構如下:
2、引入pom依賴,同上(與服務提供者依賴相同)
3、編輯application.yml文件
1 # 端口 2 server: 3 port: 7999 4 5 spring: 6 application: 7 name: cloud-order 8 cloud: 9 zookeeper: 10 connect-string: 127.0.0.1
4、編寫主啟動類
1 @SpringBootApplication 2 public class OrderMain7999 { 3 public static void main(String[] args) { 4 SpringApplication.run(OrderMain7999.class, args); 5 } 6 }
5、編輯配置類,注入RestTemplate對象
1 @Configuration 2 public class AppConfig { 3 4 /** 5 * 注入restTemplate,請用請求rest接口 6 * @return 7 */ 8 @Bean 9 // 標注此注解后,RestTemplate就具有了客戶端負載均衡能力 10 // 負載均衡技術依賴於的是Ribbon組件~ 11 // RestTemplate都塞入一個loadBalancerInterceptor 讓其具備有負載均衡的能力 12 @LoadBalanced 13 public RestTemplate restTemplate(){ 14 return new RestTemplate(); 15 } 16 }
6、編輯Controller
1 @RestController 2 @Slf4j 3 public class OrderController { 4 5 public static final String PAYMENT_URL = "http://cloud-payment-service"; 6 7 @Autowired 8 private RestTemplate restTemplate; 9 10 @GetMapping("/consumer/payment/zk") 11 public String paymentzk(){ 12 return restTemplate.getForObject(PAYMENT_URL + "/payment/zk", String.class); 13 } 14 15 }
7、啟動項目測試
1)訪問地址:http://localhost:7999/consumer/payment/zk
2)使用zookeeper客戶端登錄zookeeper服務器查看