ZooKeeper是一个分布式协调工具,可以实现注册中心功能,Spring Cloud中整合ZooKeeper时创建的服务节点是临时节点。ZooKeeper详细介绍参考文章 【ZooKeeper】ZooKeeper。
本文将给出 Spring Boot 整合 ZooKeeper 的案例。
支付服务
新建名为cloud-provider-payment8004
的支付服务Maven工程,占用端口8004。
引入 Maven 依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency>
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.9</version> </dependency>
|
需要注意,spring-cloud-starter-zookeeper-discovery
场景启动器自带一个ZooKeeper依赖,其版本可能与自己的ZooKeeper版本不兼容,从而无法启动Spring Boot项目,因此在pom文件中首先排除掉spring-cloud-starter-zookeeper-discovery
中的ZooKeeper依赖,再自己添加符合自己版本的ZooKeeper依赖。(也可能会出现log4j依赖的冲突,解决方案相同)
修改配置文件
1 2 3 4 5 6 7 8 9 10 11
| server: port: 8004
spring: application: name: cloud-provider-payment cloud: zookeeper: connect-string: 127.0.0.1:2181
|
创建主启动类
1 2 3 4 5 6 7 8 9 10 11
| import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication @EnableDiscoveryClient public class PaymentMain8004 { public static void main(String[] args) { SpringApplication.run(PaymentMain8004.class, args); } }
|
创建 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController @Slf4j public class PaymentController { @Value("${server.port}") private String serverPort;
@RequestMapping(value = "/payment/zk") public String paymentzk() { return "springcloud with zookeeper: " + serverPort + "\t" + UUID.randomUUID().toString(); } }
|
测试
启动支付服务8004注册进ZooKeeper(要先启动zookeeper的server)
1 2 3 4 5 6 7 8 9 10 11
| [zk: localhost:2181(CONNECTED) 0] ls / [services, zookeeper] [zk: localhost:2181(CONNECTED) 1] ls /services/cloud-provider-payment [a4567f50-6ad9-47a3-9fbb-7391f41a9f3d] [zk: localhost:2181(CONNECTED) 2] get /services/cloud-provider-payment/a4567f50-6ad9-47a3-9fbb-7391f41a9f3d {"name":"cloud-provider-payment","id":"a4567f50-6ad9-47a3-9fbb-7391f41a9f3d","address":"192.168.199.218","port":8004,"ss lPort":null,"payload":{"@class":"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance","id":"application-1"," name":"cloud-provider-payment","metadata":{}},"registrationTimeUTC":1612811116918,"serviceType":"DYNAMIC","uriSpec":{"pa rts":[{"value":"scheme","variable":true},{"value":"://","variable":false},{"value":"address","variable":true},{"value":" :","variable":false},{"value":"port","variable":true}]}} [zk: localhost:2181(CONNECTED) 3]
|
json格式化get /services/cloud-provider-payment/a4567f50-6ad9-47a3-9fbb-7391f41a9f3d
的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| { "name": "cloud-provider-payment", "id": "a4567f50-6ad9-47a3-9fbb-7391f41a9f3d", "address": "192.168.199.218", "port": 8004, "sslPort": null, "payload": { "@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance", "id": "application-1", "name": "cloud-provider-payment", "metadata": { } }, "registrationTimeUTC": 1612811116918, "serviceType": "DYNAMIC", "uriSpec": { "parts": [ { "value": "scheme", "variable": true }, { "value": "://", "variable": false }, { "value": "address", "variable": true }, { "value": ":", "variable": false }, { "value": "port", "variable": true } ] } }
|
订单服务
新建名为cloud-consumerzk-order80
的订单服务Maven工程,端口号为80。
引入 Maven 依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency>
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.9</version> </dependency>
|
需要注意,spring-cloud-starter-zookeeper-discovery
场景启动器自带一个ZooKeeper依赖,其版本可能与自己的ZooKeeper版本不兼容,从而无法启动Spring Boot项目,因此在pom文件中首先排除掉spring-cloud-starter-zookeeper-discovery
中的ZooKeeper依赖,再自己添加符合自己版本的ZooKeeper依赖。(也可能会出现log4j依赖的冲突,解决方案相同)
修改配置文件
1 2 3 4 5 6 7 8 9 10
| server: port: 80
spring: application: name: cloud-consumer-order cloud: zookeeper: connect-string: 127.0.0.1:2181
|
创建主启动类
1 2 3 4 5 6 7 8 9 10 11
| import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication @EnableDiscoveryClient public class OrderZKMain80 { public static void main(String[] args) { SpringApplication.run(OrderZKMain80.class, args); } }
|
业务类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import javax.annotation.Resource;
@RestController @Slf4j public class OrderZKController { public static final String INVOKE_URL = "http://cloud-provider-payment";
@Resource private RestTemplate restTemplate;
@GetMapping(value = "/consumer/payment/zk") public String paymentInfo() { String result = restTemplate.getForObject(INVOKE_URL+"/payment/zk",String.class); return result; } }
|
测试
先后运行ZooKeeper服务端,cloud-consumerzk-order80
,cloud-provider-payment8004
。
打开ZooKeeper客户端:
1 2 3 4 5
| [zk: localhost:2181(CONNECTED) 0] ls / [services, zookeeper] [zk: localhost:2181(CONNECTED) 1] ls /services [cloud-consumer-order, cloud-provider-payment] [zk: localhost:2181(CONNECTED) 2]
|
访问测试地址:http://localhost/consumer/payment/zk
原理
80客户端将从ZooKeeper中订阅8004服务端的URL信息,从而利用RestTemplate对象调用该URL对应的Rest请求,从而实现远程调用的效果