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

一、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

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

    实战配置

    # 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 不写代码"

      Logo

      汇聚全球AI编程工具,助力开发者即刻编程。

      更多推荐