Spring Cloud 零基础入门超详细教程(全功能实战版)
前言:先搞懂2个核心问题
1. 什么是微服务?
把一个大型单体应用 ,拆成多个小型、独立、可独立部署的服务,每个服务只负责一块业务(比如订单服务、用户服务、商品服务),服务之间通过网络通信协作。
类比:一个大超市拆成 水果店、蔬菜店、零食店,各自独立运营,顾客可以分别去买,商家之间也能合作供货。
2. 什么是 Spring Cloud?
Spring Cloud 是一套微服务全家桶 ,基于 Spring Boot 实现,提供了微服务架构所需的 服务注册发现、服务调用、熔断降级、网关、配置中心 等核心功能,帮你快速搭建稳定的微服务系统。
类比:微服务是"各个小店",Spring Cloud 是"小店的管理系统"------负责小店的登记(注册发现)、订单传递(服务调用)、防止某个店倒闭影响全局(熔断降级)、统一入口(网关)等。
前置准备
-
环境要求
-
JDK 8 及以上(推荐 8,兼容性最好)
-
Maven 3.6+(依赖管理工具)
-
IDEA(推荐,代码提示+一键运行)
-
基础:会 Spring Boot 简单 CRUD(不会的话先补 Spring Boot 入门)
-
-
核心组件清单(本次全用上)
| 组件 | 作用 | 通俗理解 |
|---|---|---|
| Eureka | 服务注册与发现 | 微服务的"通讯录",所有服务都在这里登记,互相能查到 |
| Ribbon | 负载均衡 | 多个相同服务时,帮你选一个(比如 2 个订单服务,轮询调用) |
| OpenFeign | 声明式服务调用 | 用接口+注解的方式调用其他服务,比 RestTemplate 更优雅 |
| Hystrix | 服务熔断降级 | 服务挂了或超时,自动"熔断"避免雪崩,返回兜底数据 |
| Gateway | 统一网关 | 微服务的"大门",所有请求都走这里,负责路由、过滤、限流 |
| Config | 分布式配置中心 | 所有服务的配置文件集中管理,支持动态刷新 |
| Sleuth + Zipkin | 链路追踪 | 追踪一次请求经过哪些服务,排查问题时用 |
步骤1:创建父工程(统一依赖管理)
微服务是多模块项目,父工程负责管理所有子模块的依赖版本,避免版本冲突。
1.1 IDEA 创建父工程
-
打开 IDEA →
New Project→ 选择Maven→ 取消Create from archetype→Next -
填写信息:
-
GroupId:
com.example(公司/组织标识) -
ArtifactId:
springcloud-demo(项目名) -
Version:
1.0-SNAPSHOT
-
-
完成创建后,删除 src 目录(父工程不需要源码)
1.2 配置父工程 pom.xml
核心:引入 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>
<!-- 1. 父依赖:Spring Boot 基础 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/>
</parent>
<!-- 2. 项目基本信息 -->
<groupId>com.example</groupId>
<artifactId>springcloud-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <!-- 多模块项目必须是 pom -->
<name>springcloud-demo</name>
<description>Spring Cloud 零基础实战</description>
<!-- 3. 统一管理 Spring Cloud 版本 -->
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version> <!-- 和 Spring Boot 2.3.x 对应 -->
</properties>
<!-- 4. Spring Cloud 依赖管理(子模块直接用,不用写版本) -->
<dependencyManagement>
<dependencies>
<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>
<!-- 5. 通用依赖(所有子模块都能继承) -->
<dependencies>
<!-- Spring Boot Web 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Lombok(简化代码,可选但推荐) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
步骤2:服务注册与发现 ------ Eureka 实战
2.1 组件解释
-
是什么 :Eureka 是 Netflix 开源的服务注册中心,分为 Eureka Server(服务端/注册中心) 和 Eureka Client(客户端/服务提供者/消费者)
-
为什么需要:微服务多了之后,服务之间不知道对方的地址和端口,Eureka 就是"通讯录"------服务启动时注册自己,调用时从通讯录查地址。
-
核心概念
-
服务注册:服务启动时把自己的信息(IP、端口、服务名)上报给 Eureka Server
-
服务发现:服务从 Eureka Server 拉取已注册的服务列表
-
2.2 搭建 Eureka Server(注册中心)
2.2.1 创建子模块
右键父工程 springcloud-demo → New → Module → Maven → 填写:
- ArtifactId:
eureka-server
2.2.2 配置 pom.xml(添加 Eureka 服务端依赖)
XML
<dependencies>
<!-- Eureka Server 核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
2.2.3 编写启动类(加注解开启 Eureka 服务端)
创建 com.example.eurekaserver.EurekaServerApplication
Java
package com.example.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @EnableEurekaServer:标记这是一个 Eureka 服务端
*/
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
2.2.4 编写配置文件 application.yml
在 resources 下创建 application.yml
YAML
server:
port: 8761 # Eureka 服务端默认端口 8761
eureka:
instance:
hostname: localhost # 服务端主机名
client:
# 是否注册自己到 Eureka(单机版不需要,集群版需要)
register-with-eureka: false
# 是否从 Eureka 拉取服务列表(单机版不需要)
fetch-registry: false
# Eureka 服务端地址(集群版填其他 Eureka 地址)
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2.2.5 启动测试
运行 EurekaServerApplication → 浏览器访问 http://localhost:8761
看到 Eureka 管理页面,说明注册中心搭建成功!
2.3 搭建服务提供者(注册到 Eureka)
以 商品服务(product-service) 为例,作为服务提供者。
2.3.1 创建子模块
ArtifactId:product-service
2.3.2 配置 pom.xml(添加 Eureka 客户端依赖)
XML
<dependencies>
<!-- Eureka 客户端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2.3.3 编写启动类(加注解开启 Eureka 客户端)
创建 com.example.productservice.ProductServiceApplication
Java
package com.example.productservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @EnableEurekaClient:标记这是 Eureka 客户端(Spring Cloud Edgware 之后可以省略,自动识别)
*/
@EnableEurekaClient
@SpringBootApplication
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
2.3.4 编写配置文件 application.yml
YAML
server:
port: 8081 # 商品服务端口
spring:
application:
name: product-service # 服务名!!!核心,其他服务通过这个名字调用
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/ # Eureka 服务端地址
instance:
prefer-ip-address: true # 注册时显示 IP 地址,方便调试
2.3.5 编写业务接口(提供一个查询商品的接口)
创建 com.example.productservice.controller.ProductController
Java
package com.example.productservice.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
// 模拟根据 ID 查询商品
@GetMapping("/product/{id}")
public String getProductById(@PathVariable Integer id) {
return "商品 ID:" + id + ",名称:小米手机";
}
}
2.3.6 启动测试
-
确保 Eureka Server 已启动
-
启动
ProductServiceApplication -
刷新 Eureka 页面
http://localhost:8761→ 看到PRODUCT-SERVICE已注册,说明成功! -
直接访问商品接口:
http://localhost:8081/product/1→ 返回商品 ID:1,名称:小米手机
步骤3:服务调用 ------ Ribbon + OpenFeign 实战
3.1 组件解释
| 组件 | 作用 | 通俗理解 |
|---|---|---|
| Ribbon | 客户端负载均衡 | 从 Eureka 拉取服务列表,选择一个服务调用(轮询、随机等策略) |
| OpenFeign | 声明式服务调用 | 基于 Ribbon 封装,用 @FeignClient 注解+接口的方式调用,不用写 RestTemplate |
3.2 搭建服务消费者(订单服务 order-service)
订单服务需要调用商品服务,获取商品信息。
3.2.1 创建子模块
ArtifactId:order-service
3.2.2 配置 pom.xml(添加 Eureka 客户端 + OpenFeign 依赖)
XML
<dependencies>
<!-- Eureka 客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- OpenFeign 依赖(内置 Ribbon) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
3.2.3 编写启动类(加注解开启 OpenFeign)
创建 com.example.orderservice.OrderServiceApplication
Java
package com.example.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @EnableFeignClients:开启 OpenFeign 功能
*/
@EnableFeignClients
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
3.2.4 编写配置文件 application.yml
YAML
server:
port: 8082 # 订单服务端口
spring:
application:
name: order-service # 服务名
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
3.2.5 方式1:基于 RestTemplate + Ribbon 调用
<3.2.5.1> 配置 RestTemplate 并开启负载均衡
创建 com.example.orderservice.config.RestTemplateConfig
Java
package com.example.orderservice.config;
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 RestTemplateConfig {
/**
* @LoadBalanced:开启 RestTemplate 的负载均衡功能(底层是 Ribbon)
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
<3.2.5.2> 编写订单控制器,调用商品服务
Java
package com.example.orderservice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
// 订单调用商品服务
@GetMapping("/order/{productId}")
public String getOrder(@PathVariable Integer productId) {
// 1. 服务名 + 接口路径(不用写 IP 和端口,Ribbon 自动从 Eureka 找)
String url = "http://product-service/product/" + productId;
// 2. 调用商品服务
String product = restTemplate.getForObject(url, String.class);
return "订单:购买了【" + product + "】";
}
}
<3.2.5.3> 测试
-
启动 Eureka Server、product-service、order-service
-
访问
http://localhost:8082/order/1→ 返回订单:购买了【商品 ID:1,名称:小米手机】 -
测试负载均衡:复制 product-service 模块,改端口为 8083,启动第二个商品服务 → 多次访问订单接口,会轮询调用 8081 和 8083 的商品服务!
3.2.6 方式2:基于 OpenFeign 声明式调用(更优雅)
<3.2.6.1> 编写 Feign 接口(绑定商品服务)
创建 com.example.orderservice.feign.ProductFeignClient
Java
package com.example.orderservice.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @FeignClient("product-service"):指定要调用的服务名
*/
@FeignClient("product-service")
public interface ProductFeignClient {
// 方法签名和商品服务的接口完全一致!
@GetMapping("/product/{id}")
String getProductById(@PathVariable("id") Integer id);
}
<3.2.6.2> 修改订单控制器,用 Feign 调用
Java
@RestController
public class OrderController {
@Autowired
private ProductFeignClient productFeignClient;
@GetMapping("/order-feign/{productId}")
public String getOrderByFeign(@PathVariable Integer productId) {
// 直接调用 Feign 接口,像调用本地方法一样!
String product = productFeignClient.getProductById(productId);
return "订单(Feign 调用):购买了【" + product + "】";
}
}
<3.2.6.3> 测试
访问 http://localhost:8082/order-feign/1 → 返回结果和 RestTemplate 方式一致,但代码更简洁!
步骤4:服务熔断降级 ------ Hystrix 实战
4.1 组件解释
-
是什么 :Hystrix 是 Netflix 开源的熔断器组件,解决服务雪崩问题
-
为什么需要 :如果商品服务挂了,订单服务一直调用它,会导致订单服务的线程池被耗尽,最终订单服务也挂了 → 雪崩。Hystrix 像保险丝,服务故障时自动熔断,返回兜底数据。
-
核心概念
-
熔断:服务故障时,停止调用,直接走降级逻辑
-
降级:服务不可用时,返回一个默认值(兜底数据)
-
4.2 集成 Hystrix 到订单服务
4.2.1 加 Hystrix 依赖
在 order-service 的 pom.xml 中添加:
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
4.2.2 启动类加注解开启 Hystrix
Java
@EnableHystrix // 开启 Hystrix 功能
@EnableFeignClients
@SpringBootApplication
public class OrderServiceApplication {
// ...
}
4.2.3 方式1:RestTemplate + Hystrix 降级
修改 OrderController,给方法加 @HystrixCommand 注解:
Java
@GetMapping("/order/{productId}")
// 指定降级方法:fallbackMethod = "getOrderFallback"
@HystrixCommand(fallbackMethod = "getOrderFallback")
public String getOrder(@PathVariable Integer productId) {
String url = "http://product-service/product/" + productId;
String product = restTemplate.getForObject(url, String.class);
return "订单:购买了【" + product + "】";
}
// 降级方法:参数和返回值必须和原方法一致!
public String getOrderFallback(Integer productId) {
return "订单:商品服务暂时不可用,商品 ID:" + productId;
}
4.2.4 方式2:OpenFeign + Hystrix 降级
<4.2.4.1> 配置 application.yml,开启 Feign 的 Hystrix 支持
YAML
feign:
hystrix:
enabled: true # 开启 Feign 整合 Hystrix
<4.2.4.2> 编写降级类(实现 ProductFeignClient 接口)
创建 com.example.orderservice.feign.fallback.ProductFeignFallback
Java
package com.example.orderservice.feign.fallback;
import com.example.orderservice.feign.ProductFeignClient;
import org.springframework.stereotype.Component;
@Component
public class ProductFeignFallback implements ProductFeignClient {
// 降级逻辑
@Override
public String getProductById(Integer id) {
return "商品服务暂时不可用(Feign 降级),商品 ID:" + id;
}
}
<4.2.4.3> 修改 Feign 接口,指定降级类
Java
@FeignClient(value = "product-service", fallback = ProductFeignFallback.class)
public interface ProductFeignClient {
// ...
}
4.2.5 测试熔断降级
-
停止 product-service 服务
-
访问
http://localhost:8082/order/1→ 返回降级信息订单:商品服务暂时不可用,商品 ID:1 -
访问
http://localhost:8082/order-feign/1→ 返回 Feign 降级信息 -
重启 product-service → 自动恢复正常调用!
步骤5:统一网关 ------ Gateway 实战
5.1 组件解释
-
是什么:Spring Cloud Gateway 是新一代网关,基于 Spring 5 + WebFlux 实现,非阻塞
-
为什么需要:
-
统一入口:所有前端请求都走网关,不用记住多个服务的地址
-
路由转发:网关根据请求路径,转发到对应的服务
-
功能扩展:支持过滤(鉴权、日志)、限流、跨域等
-
类比:网关是小区大门,所有访客都要先经过大门,保安(过滤器)检查身份,再指引到对应的住户(服务)
5.2 搭建 Gateway 网关
5.2.1 创建子模块
ArtifactId:gateway-server
5.2.2 配置 pom.xml
XML
<dependencies>
<!-- Gateway 核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Eureka 客户端(网关需要从 Eureka 拉取服务列表) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
5.2.3 编写启动类
创建 com.example.gatewayserver.GatewayServerApplication
Java
package com.example.gatewayserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class GatewayServerApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServerApplication.class, args);
}
}
5.2.4 编写配置文件 application.yml
核心:配置路由规则(请求路径 → 服务)
YAML
server:
port: 80 # 网关端口,前端直接访问 80 端口
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
# 路由1:转发到商品服务
- id: product-route
# 动态路由:lb:// + 服务名(lb = load balance 负载均衡)
uri: lb://product-service
# 路由规则:请求路径以 /product/ 开头,转发到商品服务
predicates:
- Path=/product/**
# 路由2:转发到订单服务
- id: order-route
uri: lb://order-service
predicates:
- Path=/order/**,/order-feign/** # 多个路径用逗号分隔
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
5.2.5 测试网关
-
启动所有服务(Eureka、product、order、gateway)
-
之前访问商品服务要写
http://localhost:8081/product/1→ 现在通过网关访问http://localhost/product/1 -
访问订单服务:
http://localhost/order-feign/1→ 成功! -
网关自动做了负载均衡:多次访问,会轮询调用 8081/8083 的商品服务!
步骤6:分布式配置中心 ------ Config 实战
6.1 组件解释
-
是什么:Spring Cloud Config 是分布式配置中心,集中管理所有服务的配置文件
-
为什么需要:
-
微服务多了,每个服务都有 application.yml,改配置要一个个改,重启服务 → 麻烦
-
Config 支持动态刷新配置,不用重启服务
-
-
核心架构:
-
Config Server:配置服务端,从 Git/SVN 读取配置文件
-
Config Client:配置客户端,从 Config Server 获取配置
-
6.2 搭建 Config Server(服务端)
6.2.1 准备 Git 仓库
-
新建一个 Git 仓库(比如 GitHub/Gitee)
-
在仓库中创建配置文件:
product-service-dev.yml(命名规则:服务名-环境.yml) -
写入配置内容:
YAML
# 商品服务的自定义配置
product:
name: 华为手机 # 覆盖本地配置
price: 5999
6.2.2 创建子模块
ArtifactId:config-server
6.2.3 配置 pom.xml
XML
<dependencies>
<!-- Config Server 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- Eureka 客户端(注册到 Eureka) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
6.2.4 编写启动类
Java
package com.example.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableConfigServer // 开启 Config 服务端
@EnableEurekaClient
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
6.2.5 编写配置文件 application.yml
YAML
server:
port: 8888 # Config 服务端默认端口
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://gitee.com/你的用户名/你的仓库名.git # Git 仓库地址
username: 你的 Git 用户名
password: 你的 Git 密码/令牌
search-paths: / # 配置文件所在目录
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
6.2.6 测试 Config Server
启动 ConfigServerApplication → 访问 http://localhost:8888/product-service-dev.yml
看到返回 Git 仓库中的配置内容,说明服务端搭建成功!
6.3 搭建 Config Client(客户端,以 product-service 为例)
6.3.1 修改 product-service 的 pom.xml
添加 Config 客户端依赖:
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- 动态刷新配置需要的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
6.3.2 新增配置文件 bootstrap.yml
注意:Config 配置要写在 bootstrap.yml 中,它的加载优先级高于 application.yml
YAML
spring:
cloud:
config:
name: product-service # 配置文件名前缀
profile: dev # 环境
label: master # Git 分支
uri: http://localhost:8888 # Config Server 地址
application:
name: product-service
# 暴露刷新端点(用于动态刷新配置)
management:
endpoints:
web:
exposure:
include: refresh
6.3.3 修改商品服务的 Controller,读取配置
Java
@RestController
@RefreshScope // 开启动态刷新配置的注解
public class ProductController {
// 读取 Git 配置中的 product.name
@Value("${product.name}")
private String productName;
@Value("${product.price}")
private Integer productPrice;
@GetMapping("/product/{id}")
public String getProductById(@PathVariable Integer id) {
return "商品 ID:" + id + ",名称:" + productName + ",价格:" + productPrice;
}
}
6.3.4 测试配置中心
-
启动 Config Server、product-service
-
访问
http://localhost:8081/product/1→ 返回商品 ID:1,名称:华为手机,价格:5999(读取的是 Git 配置) -
动态刷新配置:
-
修改 Git 仓库中的
product-service-dev.yml→ 把 name 改成苹果手机,price 改成 8999 -
发送 POST 请求到
http://localhost:8081/actuator/refresh(用 Postman 或 curl) -
再次访问商品接口 → 配置已刷新,返回新的商品信息!
-
步骤7:分布式链路追踪 ------ Sleuth + Zipkin 实战
7.1 组件解释
-
Sleuth :给每个请求生成一个追踪 ID,标记请求经过的服务,在日志中打印追踪信息
-
Zipkin:收集 Sleuth 的追踪数据,提供可视化界面,展示请求的调用链路
-
为什么需要:微服务中一个请求可能经过多个服务,出问题时不知道是哪个服务的锅 → 链路追踪帮你定位问题
7.2 搭建 Zipkin Server(服务端)
7.2.1 下载 Zipkin Jar 包
直接从官网下载:https://zipkin.io/pages/quickstart.html
下载命令:curl -sSL https://zipkin.io/quickstart.sh | bash -s
7.2.2 启动 Zipkin
命令行执行:java -jar zipkin.jar
启动后访问 http://localhost:9411 → 看到 Zipkin 可视化界面
7.3 客户端集成 Sleuth + Zipkin(所有服务都要加)
以 product-service 和 order-service 为例,其他服务同理。
7.3.1 加依赖
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
7.3.2 配置 application.yml
YAML
spring:
zipkin:
base-url: http://localhost:9411 # Zipkin 服务端地址
sleuth:
sampler:
probability: 1.0 # 采样率 1.0(100% 采样,生产环境可以设 0.1)
7.3.3 测试链路追踪
-
启动所有服务(包括 Zipkin)
-
通过网关访问订单接口:
http://localhost/order-feign/1 -
访问 Zipkin 界面
http://localhost:9411→ 点击Find a trace→Run Query -
看到一条追踪记录,点击进去 → 能看到请求经过
gateway-server→order-service→product-service的完整链路!
步骤8:全流程测试(所有功能串联)
-
启动所有服务:Eureka → Config → Zipkin → Product → Order → Gateway
-
通过网关访问订单 Feign 接口:
http://localhost/order-feign/1 -
验证功能:
-
服务注册发现:Eureka 页面能看到所有服务
-
负载均衡:多次访问,轮询调用 2 个商品服务
-
熔断降级:停止商品服务,返回降级信息
-
配置中心:修改 Git 配置,刷新后生效
-
链路追踪:Zipkin 能看到完整调用链
-
常见坑 & 注意事项
-
版本冲突:Spring Boot 和 Spring Cloud 版本必须对应!(比如 Boot 2.3.x 对应 Cloud Hoxton.SR12)
-
端口冲突:每个服务的端口不能重复,启动前检查端口占用
-
注解漏加 :比如
@EnableEurekaServer、@EnableFeignClients等,漏加会导致功能失效 -
配置文件优先级:bootstrap.yml > application.yml,Config 配置必须写在 bootstrap.yml