Spring Cloud 零基础教程:Eureka 实战

Spring Cloud 零基础入门超详细教程(全功能实战版)

前言:先搞懂2个核心问题

1. 什么是微服务?

一个大型单体应用 ,拆成多个小型、独立、可独立部署的服务,每个服务只负责一块业务(比如订单服务、用户服务、商品服务),服务之间通过网络通信协作。

类比:一个大超市拆成 水果店、蔬菜店、零食店,各自独立运营,顾客可以分别去买,商家之间也能合作供货。

2. 什么是 Spring Cloud?

Spring Cloud 是一套微服务全家桶 ,基于 Spring Boot 实现,提供了微服务架构所需的 服务注册发现、服务调用、熔断降级、网关、配置中心 等核心功能,帮你快速搭建稳定的微服务系统。

类比:微服务是"各个小店",Spring Cloud 是"小店的管理系统"------负责小店的登记(注册发现)、订单传递(服务调用)、防止某个店倒闭影响全局(熔断降级)、统一入口(网关)等。


前置准备

  1. 环境要求

    • JDK 8 及以上(推荐 8,兼容性最好)

    • Maven 3.6+(依赖管理工具)

    • IDEA(推荐,代码提示+一键运行)

    • 基础:会 Spring Boot 简单 CRUD(不会的话先补 Spring Boot 入门)

  2. 核心组件清单(本次全用上)

组件 作用 通俗理解
Eureka 服务注册与发现 微服务的"通讯录",所有服务都在这里登记,互相能查到
Ribbon 负载均衡 多个相同服务时,帮你选一个(比如 2 个订单服务,轮询调用)
OpenFeign 声明式服务调用 用接口+注解的方式调用其他服务,比 RestTemplate 更优雅
Hystrix 服务熔断降级 服务挂了或超时,自动"熔断"避免雪崩,返回兜底数据
Gateway 统一网关 微服务的"大门",所有请求都走这里,负责路由、过滤、限流
Config 分布式配置中心 所有服务的配置文件集中管理,支持动态刷新
Sleuth + Zipkin 链路追踪 追踪一次请求经过哪些服务,排查问题时用

步骤1:创建父工程(统一依赖管理)

微服务是多模块项目,父工程负责管理所有子模块的依赖版本,避免版本冲突。

1.1 IDEA 创建父工程

  1. 打开 IDEA → New Project → 选择 Maven → 取消 Create from archetypeNext

  2. 填写信息:

    • GroupId:com.example(公司/组织标识)

    • ArtifactId:springcloud-demo(项目名)

    • Version:1.0-SNAPSHOT

  3. 完成创建后,删除 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-demoNewModuleMaven → 填写:

  • 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 启动测试
  1. 确保 Eureka Server 已启动

  2. 启动 ProductServiceApplication

  3. 刷新 Eureka 页面 http://localhost:8761 → 看到 PRODUCT-SERVICE 已注册,说明成功!

  4. 直接访问商品接口: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> 测试
  1. 启动 Eureka Server、product-service、order-service

  2. 访问 http://localhost:8082/order/1 → 返回 订单:购买了【商品 ID:1,名称:小米手机】

  3. 测试负载均衡:复制 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 测试熔断降级
  1. 停止 product-service 服务

  2. 访问 http://localhost:8082/order/1 → 返回降级信息 订单:商品服务暂时不可用,商品 ID:1

  3. 访问 http://localhost:8082/order-feign/1 → 返回 Feign 降级信息

  4. 重启 product-service → 自动恢复正常调用!


步骤5:统一网关 ------ Gateway 实战

5.1 组件解释

  • 是什么:Spring Cloud Gateway 是新一代网关,基于 Spring 5 + WebFlux 实现,非阻塞

  • 为什么需要

    1. 统一入口:所有前端请求都走网关,不用记住多个服务的地址

    2. 路由转发:网关根据请求路径,转发到对应的服务

    3. 功能扩展:支持过滤(鉴权、日志)、限流、跨域等

类比:网关是小区大门,所有访客都要先经过大门,保安(过滤器)检查身份,再指引到对应的住户(服务)

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 测试网关
  1. 启动所有服务(Eureka、product、order、gateway)

  2. 之前访问商品服务要写 http://localhost:8081/product/1 → 现在通过网关访问 http://localhost/product/1

  3. 访问订单服务:http://localhost/order-feign/1 → 成功!

  4. 网关自动做了负载均衡:多次访问,会轮询调用 8081/8083 的商品服务!


步骤6:分布式配置中心 ------ Config 实战

6.1 组件解释

  • 是什么:Spring Cloud Config 是分布式配置中心,集中管理所有服务的配置文件

  • 为什么需要

    1. 微服务多了,每个服务都有 application.yml,改配置要一个个改,重启服务 → 麻烦

    2. Config 支持动态刷新配置,不用重启服务

  • 核心架构

    • Config Server:配置服务端,从 Git/SVN 读取配置文件

    • Config Client:配置客户端,从 Config Server 获取配置

6.2 搭建 Config Server(服务端)

6.2.1 准备 Git 仓库
  1. 新建一个 Git 仓库(比如 GitHub/Gitee)

  2. 在仓库中创建配置文件:product-service-dev.yml(命名规则:服务名-环境.yml

  3. 写入配置内容:

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 测试配置中心
  1. 启动 Config Server、product-service

  2. 访问 http://localhost:8081/product/1 → 返回 商品 ID:1,名称:华为手机,价格:5999(读取的是 Git 配置)

  3. 动态刷新配置

    • 修改 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 测试链路追踪
  1. 启动所有服务(包括 Zipkin)

  2. 通过网关访问订单接口:http://localhost/order-feign/1

  3. 访问 Zipkin 界面 http://localhost:9411 → 点击 Find a traceRun Query

  4. 看到一条追踪记录,点击进去 → 能看到请求经过 gateway-serverorder-serviceproduct-service 的完整链路!


步骤8:全流程测试(所有功能串联)

  1. 启动所有服务:Eureka → Config → Zipkin → Product → Order → Gateway

  2. 通过网关访问订单 Feign 接口:http://localhost/order-feign/1

  3. 验证功能:

    • 服务注册发现:Eureka 页面能看到所有服务

    • 负载均衡:多次访问,轮询调用 2 个商品服务

    • 熔断降级:停止商品服务,返回降级信息

    • 配置中心:修改 Git 配置,刷新后生效

    • 链路追踪:Zipkin 能看到完整调用链


常见坑 & 注意事项

  1. 版本冲突:Spring Boot 和 Spring Cloud 版本必须对应!(比如 Boot 2.3.x 对应 Cloud Hoxton.SR12)

  2. 端口冲突:每个服务的端口不能重复,启动前检查端口占用

  3. 注解漏加 :比如 @EnableEurekaServer@EnableFeignClients 等,漏加会导致功能失效

  4. 配置文件优先级:bootstrap.yml > application.yml,Config 配置必须写在 bootstrap.yml


相关推荐
程序员老徐2 小时前
Spring Security 是如何注入 Tomcat Filter 链的 —— 启动与请求源码分析
java·spring·tomcat
Leo July10 小时前
【Java】Spring Security 6.x 全解析:从基础认证到企业级权限架构
java·spring·架构
雨中飘荡的记忆12 小时前
深度详解Spring Context
java·spring
yqd66612 小时前
SpringSecurity的使用
java·spring
Mr__Miss15 小时前
JAVA面试-框架篇
java·spring·面试
蓝眸少年CY16 小时前
(第十二篇)spring cloud之Stream消息驱动
后端·spring·spring cloud
码界奇点17 小时前
基于SpringBoot+Vue的前后端分离外卖点单系统设计与实现
vue.js·spring boot·后端·spring·毕业设计·源代码管理
康小庄18 小时前
浅谈Java中的volatile关键字
java·开发语言·jvm·spring boot·spring·jetty
0和1的舞者20 小时前
基于Spring的论坛系统-前置知识
java·后端·spring·系统·开发·知识