@
目录
参考资料:
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》
ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等;
Zookeeper 是一个分布式协调工具,可以实现注册中心功能;
是 Apache Hadoop 的一个子项目,用来解决分布式应用中经常遇到的一些数据管理问题。包括:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等;
简单来说:zookeeper=文件系统+监听通知机制;
ZooKeeper 的架构通过冗余服务实现高可用性;
【注意】ZooKeeper 本身并不是注册中心,只是基于 ZooKeeper 本身的特性可以实现注册中心这个场景;
系统概述:
Znode 节点:
stat 状态信息:
属性
说明
cZxid
创建节点时的事务 ID
ctime
创建节点时的时间
mZxid
最后修改节点时的事务 ID
mtime
最后修改节点时的时间
pZxid
表示该节点的子节点列表最后一次修改的事务 ID(包括增删子节点,不包括改子节点内容)
cversion
子节点版本号,子节点每次修改版本号加 1
dataversion
数据版本号,数据每次修改该版本号加 1
aclversion
权限版本号,权限每次修改该版本号加 1
ephemeralOwner
创建该临时节点的会话的 sessionID(持久节点,该属性值为 0)
dataLength
该节点的数据长度
numChildren
该节点拥有直接子节点的数量
Znode 的节点类型:
一个示例图:
一种针对 Znode 的订阅/通知机制;
当 Znode 节点状态发生变化时或者 ZooKeeper 客户端连接状态发生变化时,会触发事件通知;
该机制在服务注册与发现中,用于服务调用者及时感知到服务提供者的变化;
ZooKeeper 提供了三种 JavaAPI 机制进行对 Znode 进行注册监听:
Watcher 事件的触发都是一次性的,客户端在发现节点修改后需要在事件回调中再次注册事件;
分布式锁:
/Exclusive_Locks
节点下创建一个临时节点 /lock
。只有一个客户端能创建成功;/lock
节点会被自动删除;/lock
节点;Master 选举:
/master-election
,只有成功创建的机器工作。其他机器针对该节点注册 Watcher 事件;/master
节点下创建一个临时有序节点,编号最小的节点表示 Master,后续的节点可以监听前一个节点的删除事件,用于触发重新选举。如下图所示:Zookeeper 的依赖如下:
如果我们直接添加这个依赖可能会出现以下问题,出现以下日志信息是说明出现 Zookeeper 版本冲突问题:
本篇或《12.1 使用 Apache Dubbo 实现远程通信》里的《5. Dubbo 使用 Zookeeper 作为注册中心》构建了如下示例;
当 Dubbo 服务启动时:
/dubbo/com.dlhjw.dubbo.service.impl.TestServiceImpl/providers
目录下创建当前服务的 URL;com.dlhjw.dubbo.service.impl.TestServiceImpl
表示发布服务的接口全路径名称;providers
表示服务提供者的类型;dubbo://ip:port
表示该服务发布的协议类型及访问地址;当 Dubbo 服务消费者启动时:
/dubbo/com.dlhjw.dubbo.service.impl.TestServiceImpl/providers
目录下子节点注册 Watcher 监听;/dubbo/com.dlhjw.dubbo.service.impl.TestServiceImpl/consumers
目录下写入自己的 URL;/dubbo/com.dlhjw.dubbo.service.impl.TestServiceImpl/providers
路径下获得所有该服务的提供方 URL 列表,然后通过负载均衡算法计算出一个地址进远程访问;客户端(在这里体现不出来)调用服务消费者的 http://consumer/zk
接口,请求消费者的资源;
接着服务消费者通过负载均衡算法调用 http://zkcloud-provider/provider/zk
接口,请求服务提供者的资源;
基于 Win10 下的 Zookeeper 服务器安装;
下载解压后:
apache-zookeeper-3.7.0-bin\apache-zookeeper-3.7.0-bin\conf
目录下,备份一份 zoo_sample.cfg 配置文件;tickTime:Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每隔 tickTime 时间就会发送一个心跳;
dataDir:Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里;
dataLogDir:Zookeeper 保存日志文件的目录;
clientPort:客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求;
注意:查看 bin 目录下的 zkEvn.cmd 里的 JAVA_HOME 名字对不对;
到 bin 目录下:
使用 Zookeeper 构建服务提供者大致与 Nacos 和 Consul 相同; Nacos 与 Consul 的构建方式详情请见《3.2 Alibaba Nacos 注册中心》与《3.4 HashiCorp Consul 注册中心》;
<!-- SpringBoot整合zookeeper客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<!--先排除自带的zookeeper-->
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加zookeeper3.4.9版本,这里可根据自己本地的下载的 zookeeper 版本进行配置-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>
Spring 管理的依赖自带 3.5.3beta 版本,与本地的下载的 zookeeper 版本对应不上,可以通过修改 pom 文件解决;
#8004表示注册到zookeeper服务器的支付服务提供者端口号
server:
port: 8004
#服务别名----注册zookeeper到注册中心名称
spring:
application:
name: zkcloud-provider
cloud:
zookeeper:
connect-string: 192.168.111.144:2181
@EnableDiscoveryClient:使用其他组件(Nacos、zookeeper、Consul)作为注册中心;
这里编写一个简单接口仅作为示例;
@RestController
public class providerController{
@Value("${server.port}")
private String serverPort;
@RequestMapping(value = "/provider/zk")
public String providerzk(){
return "springcloud with zookeeper: "+serverPort+"\t"+ UUID.randomUUID().toString();
}
}
使用 Zookeeper 构建服务消费者大致与 Nacos 和 Consul 相同; Nacos 与 Consul 的构建方式详情请见《3.2 Alibaba Nacos 注册中心》与《3.4 HashiCorp Consul 注册中心》;
同服务提供者端的依赖;
<!-- SpringBoot整合zookeeper客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<!--先排除自带的zookeeper-->
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加zookeeper3.4.9版本-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>
server:
port: 80
spring:
application:
name: zkcloud-consumer
cloud:
#注册到zookeeper地址
zookeeper:
connect-string: 192.168.111.144:2181
由于我们使用 Ribbon + RestTemplate 的负载均衡策略,因此需要在 IoC 容器中添加一个 RestTemplate JavaBean;
详情请见《4.1 基于 Ribbon 的负载均衡详解》;
该 Bean 可以在主启动类中添加;也可以在主启动类所在包或子包的 config 包中添加,如下:
@Configuration
public class ApplicationContextBean{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
我们在 controller 层开放接口给客户端,并在该接口里调用提供者的 API;
@RestController
public class ComsumerZKController{
public static final String INVOKE_URL = "http://zkcloud-provider";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/zk")
public String paymentInfo(){
String result = restTemplate.getForObject(INVOKE_URL+"/provider/zk", String.class);
System.out.println("消费者调用提供者获取服务--->result:" + result);
return result;
}
}
新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!
手机扫一扫
移动阅读更方便
你可能感兴趣的文章