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


相关推荐
our_times9 分钟前
2026年Java开发者破局指南:Spring AI 2.0 与 Agent 开发实战
java·人工智能·spring
wear工程师1 小时前
@Transactional 标了却没开事务?先看这次调用有没有经过代理
java·spring
野蛮人6号2 小时前
黑马天机学堂系列问题之域名无法正常使用
java·spring cloud·天机学堂
静水楼台x4 小时前
spring security
java·数据库·spring
咖啡八杯13 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
糖果店的幽灵13 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
Suhan4219 小时前
IDEA 设置启动参数和环境变量
spring boot·spring·编辑器·idea
橘子海全栈攻城狮1 天前
【最新源码】基于SpringBoot + Vue的超市管理系统的设计与实现D002
java·开发语言·vue.js·spring boot·后端·spring
空中湖1 天前
Spring AI Function Calling 完全指南:让 AI 查数据库、调 API、发通知
数据库·人工智能·spring
风起洛阳@不良使1 天前
spring中xml和注解开发的对比
xml·java·spring