前言
服务注册中心可以用Eureka、Zookeeper、Consul等三种技术方案实现,Eureka我已经介绍过了,本次简单介绍下用Zookeeper实现服务注册中心。
Zookeeper是什么
ZooKeeper 是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
ZooKeeper 一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心
准备工作
- 安装Zookeeper并启动,我的阿里云已经安装了Zookeeper,版本号是
zookeeper-3.4.13
- 关于Zookeeper的安装和使用后续会出教程,本次不做介绍😊
搭建服务者提供者
-
新建Module
zk-client8013
充当服务者提供者(就是一个SpringBoot项目,这里不做演示) -
改POM文件
<!--整合zookeeper客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency> <!--必须添加的依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--非必须,它的作用用于监控以及健康检查--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.5.2</version> </dependency>
-
写application.yml
server: port: 8013 #端口号 spring: application: name: zk-service8013 #服务名称 cloud: zookeeper: connect-string: 139.196.195.43:2181 #zookeeper服务器所在机器的IP和ZK端口号
-
主启动类
/** * EnableDiscoveryClient作用:把服务注册到ZK或者Consul上去 */ @SpringBootApplication @EnableDiscoveryClient public class ZKClientMain8013 { public static void main(String[] args) { SpringApplication.run(ZKClientMain8013.class,args); } }
-
业务类
@RestController @Slf4j public class testController { @Value("${server.port}") private String port; @GetMapping(value = "/eat") public String eat(){ return "吃饭喽!服务端口号是"+port+"-"+ IdUtil.simpleUUID(); } }
-
启动报错😂百度了一下是jar包冲突
-
产生原因:
spring-cloud-starter-zookeeper-discovery
依赖传递了zookeeper-3.5.3-beta
,而我阿里云上安装的是zookeeper-3.4.13
所以造成了版本冲突
-
解决方案:排除
zookeeper-3.5.3-beta
,添加zookeeper-3.4.13
依赖<!--整合zookeeper客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <!--排除zookeeper-3.5.3--> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <!--添加zookeeper3.4.13--> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.13</version> </dependency>
-
再次启动还是报错,又百度了一下结果日志包又冲突了
-
产生原因,
zookeeper-3.4.13
依赖中传递依赖了slf4j-log4j12
,而SpringBoot默认使用的是logback
作为日志的输出
从上图可以看出,logback-classic-1.2.3.jar
和slf4j-log4j12-1.7.29.jar
中StaticLoggerBinder路径一样,因此加载出错 -
解决方案:排除
slf4j-log4j12-1.7.29.jar
<!--添加zookeeper3.4.13-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
<!--排除slf4j-log4j12-->
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
- 再次启动😄终于成功了,ZK中节点也添加进来了。切记项目启动之前ZK一定要先启动
搭建服务消费者
-
新建Module
zk-client80
充当服务消费者(跟服务提供者一个套路) -
改POM文件
<dependencies> <!--整合zookeeper客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <!--排除zookeeper-3.5.3--> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <!--添加zookeeper3.4.13--> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.13</version> <!--排除slf4j-log4j12--> <exclusions> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <!--必须添加的依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--非必须,它的作用用于监控以及健康检查--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
写application.yml
server: port: 80 #端口号 spring: application: name: zk-consumption80 #服务名称 cloud: zookeeper: connect-string: 139.196.195.43:2181 #zookeeper服务器所在机器的IP和端口号
-
主启动类
@SpringBootApplication @EnableDiscoveryClient public class ZKClientMain { public static void main(String[] args) { SpringApplication.run(ZKClientMain.class,args); } }
-
注入RestTemplate实现远程调用
@Configuration public class BeanConfig { @Bean @LoadBalanced //开启负载均衡的功能 public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
-
业务类
@RestController @Slf4j public class TestController { /** * ZKSERVICE8013:就是ZK上注册的节点名称 */ private static final String ZKSERVICE8013 = "http://zk-service8013"; @Resource private RestTemplate restTemplate; @GetMapping(value = "/eat") public String eat(){ return restTemplate.getForObject(ZKSERVICE8013+"/eat",String.class); } }
-
启动zk-client80:访问
http://127.0.0.1:80/eat
多说两句
-
zookeeper中的节点分为临时节点和持久节点两大类,我们的服务注册进zookeeper之后默认是临时还是持久呢?
答:是临时的 -
本次只是单机版的zookeeper实现了注册中心,后期有时间会出zookeeper的基础入门,到时候会涉及到集群版本的服务注册中心