Spring Cloud Zookeeper 是一个用于构建分布式系统的工具,它利用 Apache Zookeeper 提供的服务来实现服务注册与发现、配置管理、负载均衡等功能。具体来说,Spring Cloud Zookeeper 可以做以下几件事情:
服务注册与发现:通过 Zookeeper,微服务可以在启动时将自己注册到 Zookeeper 中,其他服务可以通过 Zookeeper 查找并调用这些服务。
配置管理:Spring Cloud Zookeeper 可以集中管理应用程序的配置,允许开发者在 Zookeeper 中存储配置信息,并在应用启动时加载这些配置。
负载均衡:通过 Zookeeper,Spring Cloud 可以实现对服务的负载均衡,确保请求能够均匀地分配到多个服务实例上。
集群管理:Zookeeper 可以帮助管理微服务的集群状态,监控服务的健康状况,并在服务出现故障时进行相应的处理。
分布式锁:Zookeeper 提供了分布式锁的功能,可以用于控制对共享资源的访问,确保数据的一致性。
事件通知:Zookeeper 支持观察者模式,服务可以监听特定节点的变化,并在节点状态变化时收到通知,从而实现动态配置更新等功能。
version: '3'
services:
zookeeper:
image: zookeeper:3.7.0
container_name: zookeeper
restart: unless-stopped
volumes:
- "./zookeeper/data:/data"
- "./zookeeper/datalog:/datalog"
ports:
- "2181:2181"
# webui
zookeeper-webui:
image: tobilg/zookeeper-webui
container_name: zookeeper-webui
restart: unless-stopped
environment:
ZK_DEFAULT_NODE: zookeeper:2181
depends_on:
- zookeeper
links:
- zookeeper
ports:
- "8089:8080"
docker run
docker-compose -f docker-compose-zookeeper.yml -p zookeeper up -d
可视化界面访问地址:[http://ip地址:8089] ,输入 [{宿主主机ip}:2181/]进入
我们将创建两个微服务:service-a
和 service-b
。service-a
将注册到 Zookeeper,并能够调用 service-b
。
service-a
使用 Spring Initializr 创建一个新的 Spring Boot 项目,选择以下依赖:
在 pom.xml
中添加 Spring Cloud Zookeeper 依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
application.yml
在 src/main/resources/application.yml
中配置 Zookeeper 地址:
spring:
application:
name: service-a
cloud:
zookeeper:
connect-string: localhost:2181
server:
port: 8080
创建一个简单的 REST 控制器:
@RestController
@RequestMapping("/service-a")
public class ServiceAController {
@GetMapping("/hello")
public String hello() {
return "Hello from Service A!";
}
}
service-b
同样使用 Spring Initializr 创建另一个 Spring Boot 项目,选择以下依赖:
在 pom.xml
中添加 Spring Cloud Zookeeper 依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
application.yml
在 src/main/resources/application.yml
中配置 Zookeeper 地址:
spring:
application:
name: service-b
cloud:
zookeeper:
connect-string: localhost:2181
server:
port: 8081
创建一个简单的 REST 控制器,调用 service-a
:
@RestController
@RequestMapping("/service-b")
public class ServiceBController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/call-a")
public String callServiceA() {
String url = "http://service-a/service-a/hello";
return restTemplate.getForObject(url, String.class);
}
}
在 ServiceBApplication
类中添加 RestTemplate
Bean:
service-b
中调用 service-a
时,如果没有使用 @LoadBalanced
注解,RestTemplate
将尝试直接使用你提供的 URL(如 http://service-a/service-a/hello
)。如果 service-a
的主机名无法解析(如 UnknownHostException
),则会导致调用失败。@LoadBalanced
后,RestTemplate
会使用 Spring Cloud 的负载均衡机制,自动将服务名(如 service-a
)解析为实际的服务实例地址。这是通过与服务注册中心(如 Zookeeper)进行交互来实现的。@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
分别启动 service-a
和 service-b
。你可以在浏览器中访问以下 URL 测试:
service-a
:http://localhost:8080/service-a/hello
service-b
:http://localhost:8081/service-b/call-a
,这将调用 service-a
的接口并返回结果。