Spring Cloud 5 大组件 · 单个服务开发顺序

注册中心 → 远程调用 → 负载均衡 → 服务降级 → 网关

一、5 大组件的依赖关系开发顺序的灵魂

复制代码
                    ┌──────────────┐
                    │  1. 注册中心  │  ← 第 1 步:Eureka/Nacos 搭起来
                    │  (Eureka)    │
                    └──────┬───────┘
                           │ 服务注册
                           ↓
                    ┌──────────────┐
                    │ 2. 远程调用  │  ← 第 2 步:Feign 远程调用其他服务
                    │  (Feign)     │
                    └──────┬───────┘
                           │ 调用时
                           ↓
                    ┌──────────────┐
                    │ 3. 负载均衡  │  ← 第 3 步:Ribbon 选哪个实例
                    │  (Ribbon)    │
                    └──────┬───────┘
                           │ 调用失败
                           ↓
                    ┌──────────────┐
                    │ 4. 服务降级  │  ← 第 4 步:Hystrix/Sentinel 熔断
                    │  (Hystrix)   │
                    └──────┬───────┘
                           │ 外部访问
                           ↓
                    ┌──────────────┐
                    │   5. 网关    │  ← 第 5 步:Gateway 入口路由
                    │  (Gateway)   │
                    └──────────────┘

核心:1 步都不能乱------没有注册中心,其他 4 个组件都没法用

二、项目实战4 个 JVM 服务

复制代码
                    ┌──────────────────────┐
                    │ Eureka Server        │  ← 注册中心
                    │ (8761)               │
                    └──────────┬───────────┘
                               │
        ┌──────────────────────┼──────────────────────┐
        │                      │                      │
┌───────▼────────┐    ┌────────▼────────┐    ┌───────▼────────┐
│ 报表服务        │    │ 数据采集服务     │    │ 告警服务        │
│ (8081)         │    │ (8082)           │    │ (8083)         │
└────────────────┘    └─────────────────┘    └────────────────┘
        ▲                      ▲                      ▲
        │                      │                      │
        └────── Gateway (9000) 网关统一入口 ──────────┘

老哥开发 4 个服务的顺序MOVA 项目真实开发流程):

1.搭 Eureka Server

2.搭数据采集服务(注册 Eureka)

3.搭报表服务(注册 Eureka + Feign 远程调用采集)

4.搭告警服务(注册 Eureka + Feign 远程调用报表)

5.加 Ribbon 负载均衡

6.加 Hystrix 熔断

7.加 Gateway 网关

三、单个服务开发 5 步详解

3.1 第 1 步:注册中心Eureka / Nacos

为什么先搞? 因为没有注册中心,服务之间互相找不到

复制代码
// 1. Eureka Server 启动类
@SpringBootApplication
@EnableEurekaServer  // ⚠️ 启用 Eureka Server
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

// 2. Eureka Server 配置
server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  client:
    register-with-eureka: false  # 自己是 Server
    fetch-registry: false

// 3. 业务服务(报表服务)启动类
@SpringBootApplication
@EnableEurekaClient  // ⚠️ 启用 Eureka Client(注册到 Eureka)
public class ReportApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReportApplication.class, args);
    }
}

// 4. 业务服务配置
spring:
  application:
    name: mova-report-service  # ⚠️ 服务名(Feign 调用用)
eureka:
  client:
    service-url:
      defaultZone: http://eureka-server:8761/eureka/

关键点

  • ⚠️ Eureka Server 自己不注册到 Eurekaregister-with-eureka: false
  • ⚠️ 业务服务启动时自动注册@EnableEurekaClient
  • ⚠️ 服务名很重要(Feign 调用时用)
3.2 第 2 步:远程调用Feign

为什么第二步? 因为服务注册到 Eureka 后,才能用服务名远程调用

老哥 MOVA 实战代码(报表服务远程调用数据采集服务):

复制代码
// 1. Feign 接口(声明式)
@FeignClient(name = "data-collect-service")  // ⚠️ 服务名(Eureka 注册的)
public interface DataCollectFeignClient {
    
    @GetMapping("/api/collect/status")
    Result<CollectStatus> getStatus();
    
    @PostMapping("/api/collect/exec")
    Result<Void> execute(@RequestBody CollectRequest request);
}

// 2. 启动类启用 Feign
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients  // ⚠️ 启用 Feign
public class ReportApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReportApplication.class, args);
    }
}

// 3. 业务调用(像本地方法)
@Service
public class ReportService {
    
    @Autowired
    private DataCollectFeignClient dataCollectClient;
    
    public Report generateReport(Long reportId) {
        // 1. 远程调用数据采集服务
        CollectStatus status = dataCollectClient.getStatus().getData();
        
        // 2. 业务处理
        return processReport(reportId, status);
    }
}

关键点

  • ⚠️ @FeignClient(name="...") 的 name = Eureka 注册的服务名
  • ⚠️ 接口的 URL = 数据采集服务的 URL(不是 Eureka 地址)
  • ⚠️ Feign 自动把方法调用转成 HTTP 请求

Feign 自动做的事

  • 找 Eureka 拿服务列表
  • 用 Ribbon 选一个实例(默认轮询
  • 发 HTTP 请求
  • 把响应反序列化成方法返回值
3.3 第 3 步:负载均衡Ribbon

为什么第三步? 因为Feign 已经集成了 Ribbon默认轮询策略只需要"配策略",不写代码

实战配置

复制代码
# application.yml(报表服务)
data-collect-service:  # ⚠️ Feign Client 的服务名
  ribbon:
    # 1. 负载均衡策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule  # 权重响应时间
    
    # 2. 连接超时
    ConnectTimeout: 3000
    
    # 3. 读取超时
    ReadTimeout: 5000
    
    # 4. 重试次数
    MaxAutoRetries: 1
    
    # 5. 重试下一个实例
    MaxAutoRetriesNextServer: 2

或者用全局配置(影响所有 Feign Client):

复制代码
@Configuration
public class RibbonConfig {
    
    @Bean
    public IRule ribbonRule() {
        return new WeightedResponseTimeRule();  // 权重响应时间
    }
}

关键点

  • ⚠️ Ribbon 不需要单独启用(Feign 已经集成)
  • ⚠️ Feign 调用 = Ribbon 负载均衡 + HTTP 请求
  • ⚠️ Ribbon 客户端均衡(消费者自己选实例,不同于 Nginx 服务端均衡)

7 大策略

策略 适用场景
RoundRobinRule(默认) 通用场景
RandomRule 通用场景
WeightedResponseTimeRule 推荐(性能好的实例权重高)
BestAvailableRule 高峰期
RetryRule 关键业务
ZoneAvoidanceRule 多区域部署
AvailabilityFilteringRule 故障剔除

项目实战

  • 报表 用 WeightedResponseTimeRule
  • 关键功能 用 RetryRule(重试 3 次)
3.4 第 4 步:服务降级Hystrix / Sentinel

为什么第四步? 因为远程调用可能失败 (服务宕机 / 网络超时),降级是兜底

实战代码

复制代码
// 1. Feign 接口 + Fallback 降级
@FeignClient(name = "data-collect-service", 
             fallback = DataCollectFallback.class)  // ⚠️ 降级类
public interface DataCollectFeignClient {
    
    @GetMapping("/api/collect/status")
    Result<CollectStatus> getStatus();
}

// 2. Fallback 降级类(实现 Feign 接口)
@Component
public class DataCollectFallback implements DataCollectFeignClient {
    
    @Override
    public Result<CollectStatus> getStatus() {
        log.warn("数据采集服务熔断,返回兜底数据");
        // ⚠️ 关键:返回兜底数据(不是抛异常)
        return Result.ok(new CollectStatus("UNKNOWN", "服务降级"));
    }
}

// 3. 启用 Hystrix(application.yml)
feign:
  hystrix:
    enabled: true  # ⚠️ 老版本用这个
    
hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 5000  # 5 秒超时
      circuitBreaker:
        requestVolumeThreshold: 10  # 10 次请求统计
        errorThresholdPercentage: 50  # 50% 失败率打开熔断
        sleepWindowInMilliseconds: 10000  # 10 秒后进入半开

// 4. 启用 Hystrix 启动类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix  // ⚠️ 启用 Hystrix
public class ReportApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReportApplication.class, args);
    }
}

关键点

  • ⚠️ Hystrix = 4 大机制(熔断 + 降级 + 隔离 + 限流)
  • ⚠️ Fallback 必须实现 Feign 接口(不是 @HystrixCommand 那种)
  • ⚠️ 降级返回兜底数据(不是抛异常)

Hystrix 3 种状态

复制代码
关闭(Closed):正常调用,失败率 < 50%
  ↓ 失败率 > 50%(10 秒内 10 个请求中 5 个失败)
打开(Open):快速失败,直接返回 Fallback
  ↓ 10 秒后
半开(Half-Open):试探调用 1 个
  ↓ 成功
关闭(Closed):恢复正常

项目实战

  • 报表 Hystrix 熔断,避免报表雪崩
  • 故障发现时间从 30 分钟降至 30 秒

⚠️ 注意Spring Cloud 2020+ 改用 Resilience4j 替代 Hystrix新项目推荐用 Sentinel

3.5 第 5 步:网关Gateway / Zuul

为什么第五步? 因为所有服务都搭好后,才需要统一入口

实战配置

XML 复制代码
# application.yml(独立 Gateway 服务)
server:
  port: 9000
spring:
  application:
    name: mova-gateway
  cloud:
    gateway:
      # 1. 路由配置
      routes:       
        - id: mova-report
          uri: lb://mova-report-service  # ⚠️ lb = 负载均衡
          predicates:
            - Path=/api/mova/**
          filters:
            - StripPrefix=2  # 去掉 /api/mova 前缀
        
        - id: mpvs-mask
          uri: lb://mpvs-mask-service
          predicates:
            - Path=/api/mpvs/**
        
        - id: spdb-collect
          uri: lb://spdb-collect-service
          predicates:
            - Path=/api/spdb/**
      
      # 2. 全局跨域
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOriginPatterns: "*"
            allowedMethods: "*"
      
      # 3. 限流
      redis:
        rate-limiter:
          replenish-rate: 100   # 每秒 100 个请求
          burst-capacity: 200  # 突发 200 个

复制代码
// 启动类
@SpringBootApplication
@EnableDiscoveryClient  // ⚠️ Gateway 也注册到 Eureka
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

关键点

  • ⚠️ uri: lb://xxx 中的 lb = LoadBalancer(自动负载均衡)
  • ⚠️ predicates = 路由规则(Path / Header / Cookie 等)
  • ⚠️ filters = 过滤(鉴权 / 限流 / 重写路径)

Gateway 4 大功能

1.路由:根据 Path 转发

2.鉴权:JWT / OAuth2

3.限流:Redis 限流

4.熔断:Hystrix / Sentinel

四、5 大组件协同工作流完整链路

复制代码
外部用户请求
    ↓
1. Gateway 网关(9000 端口)
   ├─ 鉴权(JWT 验证)
   ├─ 限流(Redis 限流 100 QPS)
   └─ 路由(Path=/api/mova/**)
    ↓
2. Ribbon 负载均衡(从 Eureka 拉服务列表,选 1 个实例)
   ↓
3. Feign 远程调用(mova-report-service)
   ↓
4. Hystrix 熔断保护(调用失败熔断,返回 Fallback)
   ↓
5. Eureka 服务发现(找 mova-report-service 的 IP:Port)
   ↓
目标服务执行(mova-report-service)
    ↓
返回结果

五、5 大组件的依赖关系

"5 大组件的依赖顺序就是开发顺序

1.注册中心 (Eureka)------ 基础,没有它其他 4 个都没法用

2.远程调用 (Feign)------ 核心,用服务名调用其他服务

3.负载均衡 (Ribbon)------ Feign 自带只配策略不写代码

4.服务降级 (Hystrix)------ 兜底,调用失败时返回 Fallback

5.网关 (Gateway)------ 入口,所有请求统一入口

开发顺序:Eureka Server → 数据采集服务 → 报表服务 → 告警服务 → 加 Ribbon → 加 Hystrix → 加 Gateway。"

六、完整代码模板

6.1 父 pom.xml 依赖
复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
</parent>

<properties>
    <spring-cloud.version>2021.0.8</spring-cloud.version>
</properties>

<dependencies>
    <!-- 1. Eureka 客户端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <!-- 2. Feign 远程调用 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    <!-- 3. Hystrix 熔断(Spring Cloud 2021 改 Resilience4j)-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
    <!-- 4. Gateway 网关(独立服务)-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
</dependencies>
7.2 Eureka Server 完整配置
复制代码
# application.yml(Eureka Server)
server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka-server:8761/eureka/
  server:
    enable-self-preservation: true
    eviction-interval-timer-in-ms: 5000
7.3 业务服务完整配置
复制代码
# application.yml(报表服务)
server:
  port: 8081
spring:
  application:
    name: mova-report-service

# 1. Eureka
eureka:
  client:
    service-url:
      defaultZone: http://eureka-server:8761/eureka/
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 30
    lease-expiration-duration-in-seconds: 90

# 2. Ribbon(Feign 自带)
data-collect-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
    ConnectTimeout: 3000
    ReadTimeout: 5000
    MaxAutoRetries: 1
    MaxAutoRetriesNextServer: 2

# 3. Feign + Hystrix
feign:
  hystrix:
    enabled: true
  client:
    config:
      default:
        connectTimeout: 3000
        readTimeout: 5000

hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 5000
      circuitBreaker:
        requestVolumeThreshold: 10
        errorThresholdPercentage: 50
        sleepWindowInMilliseconds: 10000
7.4 Gateway 完整配置
复制代码
# application.yml(独立 Gateway 服务)
server:
  port: 9000
spring:
  application:
    name: mova-gateway
  cloud:
    gateway:
      routes:
        - id: mova-report
          uri: lb://mova-report-service
          predicates:
            - Path=/api/mova/**
          filters:
            - StripPrefix=2
      redis:
        rate-limiter:
          replenish-rate: 100
          burst-capacity: 200

七、记忆口诀

"5 大组件开发顺序:注册 → 调用 → 均衡 → 降级 → 网关"

"1 不能乱:没有注册中心,其他 4 个都用不了"

"Feign 自带 Ribbon,Ribbon 不写代码"

相关推荐
Boop_wu2 小时前
[Spring Cloud] Nacos核心功能详解:从负载均衡到配置中心的全链路实践
spring·spring cloud·负载均衡
Wyc724092 小时前
Gateway
spring cloud
我星期八休息2 小时前
Linux系统编程—mmap文件映射
java·linux·运维·服务器·数据库·mysql·spring
道友可好2 小时前
AI 怎么自己跑完一个 6 小时的任务?
前端·人工智能·后端
phltxy2 小时前
Spring AI 智能咨询系统综合实战
java·人工智能·spring
java1234_小锋2 小时前
Spring Boot 中 Starter 是什么?它的核心规范有哪些?请说明如何自定义一个 Starter。
java·spring boot·后端
雪隐2 小时前
AI股票小助手09-结果展示
人工智能·后端
VitoChang2 小时前
前端也能快速入门后端! NestJS前台和后台的Auth认证
前端·后端
XovH2 小时前
Redis 从入门到精通:性能调优与多语言客户端对比
后端