先跟大家说下核心需求:搭建父子工程统一管理依赖,实现Eureka注册中心(可跨项目引入),补充Zookeeper注册中心实操,再详细对比两者区别,吃透CAP定理,帮大家避开选型和实操的坑。


一、先搞懂基础:为什么要建父子工程?
做微服务项目,肯定会有多个模块(比如注册中心、订单服务、用户服务),如果每个模块都单独管理依赖版本,很容易出现版本冲突,后期维护起来也麻烦。
父子工程的核心作用就是:父工程统一管理所有依赖版本,子工程直接继承父工程,不用重复写版本号,既规范又省心。而且咱们的注册中心写在父工程下的子模块里,其他项目也能轻松引入使用。
实操:Maven父子工程搭建(完整可复制)
1. 父工程(cloud-parent):只做版本管理,不写业务代码
父工程的packaging必须设为pom,核心是dependencyManagement标签,统一管理Spring Boot和Spring Cloud的版本,避免版本冲突。
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 父工程GAV,可根据自己的项目修改 -->
<groupId>com.example</groupId>
<artifactId>cloud-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>cloud-parent</name>
<!-- 统一管理版本号,子工程直接引用,不用写version -->
<properties>
<spring.boot.version>2.7.18</spring.boot.version>
<spring.cloud.version>2021.0.5</spring.cloud.version>
</properties>
<!-- 依赖版本管理,子工程继承后直接使用依赖 -->
<dependencyManagement>
<dependencies>
<!-- Spring Boot 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud 核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2. 子工程创建注意事项
后续的Eureka注册中心、业务微服务(比如order-service),都作为父工程的子模块创建,创建时选择"继承父工程",就能直接使用父工程管理的依赖,不用再单独指定版本。
二、实操:Eureka注册中心(可跨项目引入,附避坑指南)
Eureka是Spring Cloud原生的注册中心,上手简单,自带控制台,适合新手和中小微服务项目。之前有小伙伴反馈,访问http://127.0.0.1:10010/eureka/报"URL拼写可能存在错误",其实是配置或启动类漏了关键步骤,下面的完整配置能直接避开这个坑!
1. Eureka Server(注册中心模块:eureka-server)
pom.xml依赖(子模块)
继承父工程后,直接引入Eureka服务端依赖,不用写版本号:
XML
<parent>
<groupId>com.example</groupId>
<artifactId>cloud-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>eureka-server</artifactId>
<dependencies><!-- Eureka服务端依赖,核心依赖不能少 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.yml配置(关键!避坑核心)
这里沿用大家给的端口10010,补充完整配置,解决URL访问报错的问题:
java
server:
port: 10010 # 注册中心端口,可自定义,记住这个端口,后续客户端要用到
spring:
application:
name: eureka-server # 注册中心服务名,不能少
eureka:
instance:
hostname: localhost # 本地部署,填写localhost即可
client:
# 重点1:自身是注册中心,不用把自己注册到注册中心,设为false
register-with-eureka: false
# 重点2:单点注册中心,不用从其他注册中心获取服务列表,设为false
fetch-registry: false
# 重点3:配置注册中心地址,客户端注册时要用到这个地址,拼写不能错!
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动类(必须加注解!否则启动失败)
启动类一定要加@EnableEurekaServer注解,告诉Spring这是一个Eureka注册中心,这是很多新手容易漏的步骤,也是报错的常见原因之一:
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer // 开启Eureka注册中心功能,缺一不可
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
启动测试(避坑提示)
启动EurekaServerApplication后,访问:http://127.0.0.1:10010/eureka/ ,如果能看到Eureka控制台,说明注册中心搭建成功!
如果还是报错"URL拼写可能存在错误",检查3点:① 启动类加了@EnableEurekaServer;② yml中defaultZone的URL拼写正确(末尾有/eureka/);③ 端口没有被占用。
2. Eureka Client(需要注册的微服务,比如order-service)
其他业务微服务(比如订单服务、用户服务),只要引入Eureka客户端依赖,配置注册中心地址,就能自动注册到Eureka。
pom.xml依赖
java
<parent>
<groupId>com.example</groupId>
<artifactId>cloud-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>order-service</artifactId>
<dependencies><!-- Eureka客户端依赖,用于注册到注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
application.yml配置
java
spring:
application:
name: order-service # 微服务名称,注册到Eureka后显示的名称
server:
port: 8081 # 微服务自身端口,可自定义
eureka:
client:
# 配置Eureka注册中心地址,和上面server的defaultZone一致
service-url:
defaultZone: http://127.0.0.1:10010/eureka/
启动order-service,刷新Eureka控制台,就能看到order-service已经成功注册,完美!
三、实操:Zookeeper注册中心(对比学习,附基础配置)
Zookeeper原本是分布式协调工具,也能作为注册中心使用,特点是一致性强,适合对数据一致性要求高的场景。和Eureka相比,它的部署和配置略有不同,下面是完整实操步骤。
1. 先安装Zookeeper(本地部署,简单版)
新手直接下载稳定版本,步骤很简单:
-
下载Zookeeper:推荐版本3.8.0(稳定版),官网或国内镜像均可下载;
-
解压后,进入bin目录,启动Zookeeper:
-
Windows:双击zkServer.cmd(如果报错,检查Java环境变量是否配置);
-
Linux/Mac:执行 ./zkServer.sh start ;
-
-
启动成功后,默认端口是2181,不用额外配置。
2. 微服务注册到Zookeeper(客户端配置)
和Eureka不同,Zookeeper没有单独的"服务端"模块,微服务只要引入Zookeeper的discovery依赖,配置连接地址,就能自动注册。
pom.xml依赖
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
application.yml配置
java
spring:
application:
name: order-service # 微服务名称,注册到ZK后显示
cloud:
zookeeper:
connect-string: localhost:2181 # ZK连接地址,默认端口2181
启动微服务,Zookeeper会自动将服务注册进去,由于ZK没有自带控制台,我们可以用ZK的客户端工具(比如ZooInspector)查看注册的服务信息。
四、重点:Eureka vs Zookeeper 详细对比(新手必看)
很多小伙伴纠结选Eureka还是Zookeeper,其实核心看你的项目需求,下面从多个维度对比,一目了然,避免踩坑:
| 对比维度 | Eureka | Zookeeper |
|---|---|---|
| 开发语言 | Java(和Spring Cloud无缝集成) | Java(Apache开源,通用分布式工具) |
| 集群机制 | 对等节点(peer):所有节点地位平等,没有主从之分,集群搭建简单 | 主从模式(Leader/Follower):有一个Leader节点,其他是Follower,选主期间不可用 |
| 健康检查 | 客户端心跳:客户端定期向注册中心发送心跳,超时未发送则剔除服务 | 临时节点:客户端和ZK建立连接后,创建临时节点,断连后节点自动删除(相当于健康检查) |
| 易用性 | 极高:自带控制台,配置简单,启动就能用,新手友好 | 中等:需要单独安装ZK,无自带控制台,需借助第三方工具查看服务 |
| 核心优势 | 高可用:集群节点平等,某个节点故障不影响整体服务 | 强一致性:数据同步快,适合对数据一致性要求高的场景 |
| 缺点 | 已进入维护模式,不再更新新功能,只修复重大bug | 部署复杂,选主期间不可用,不适合频繁上下线的大规模微服务 |
| 适用场景 | 中小微服务、新手项目、对高可用要求高,对一致性要求不高的场景 | 分布式协调、分布式锁、配置中心,对数据一致性要求高的场景 |
五、吃透CAP定理:Eureka和Zookeeper分别属于哪种?
CAP定理是分布式系统的基础,很多面试都会问:Eureka和Zookeeper在CAP定理中属于哪种?其实核心记住"分布式系统必须保证P,二选一C和A"就够了。
1. 先搞懂CAP三个字母的含义(通俗版)
-
C(Consistency):一致性:所有节点在同一时间,数据完全相同。比如你更新了服务信息,所有注册中心节点都要同步更新,保证大家看到的信息一致。
-
A(Availability):可用性:服务随时可用,只要客户端请求,就一定能得到响应(不管响应的是旧数据还是新数据),不会出现"服务不可用"的情况。
-
P(Partition tolerance):分区容错性:网络出现分区(比如部分节点断网),系统依然能正常工作,不会因为网络问题导致整个系统瘫痪。
重点:分布式系统必须保证P(分区容错性),因为网络故障是不可避免的,所以只能在C(一致性)和A(可用性)之间二选一。
2. Eureka和Zookeeper的CAP归属(必记)
-
**Eureka:AP(可用性+分区容错性)**Eureka优先保证A和P,不保证强一致性。比如某个节点故障,其他节点依然能正常提供服务(可用性);网络分区时,各节点独立工作,数据最终会同步一致(最终一致性),不会因为网络问题导致服务不可用。
-
**Zookeeper:CP(一致性+分区容错性)**Zookeeper优先保证C和P,不保证高可用性。比如ZK集群选主期间,整个集群会不可用,直到选出新的Leader;但一旦选主成功,所有节点的数据都是一致的,适合对数据一致性要求高的场景。
六、总结(新手直接背,面试不踩坑)
-
父子工程:父工程统一管理依赖版本,子工程继承,避免版本冲突,注册中心模块可跨项目引入;
-
Eureka:AP架构,易用、高可用,适合中小微服务,核心是Server加@EnableEurekaServer,Client加依赖和注册地址;
-
Zookeeper:CP架构,强一致性,适合分布式协调,核心是安装ZK,Client加依赖和连接地址;
-
选型建议:新手/中小微服务选Eureka,对一致性要求高选Zookeeper;
-
避坑重点:Eureka启动类别漏@EnableEurekaServer,URL拼写要正确;ZK启动前先配置Java环境。