【Java实战㊴】从0到1:Spring Cloud开启Java微服务实战之旅

发布于:2025-09-11 ⋅ 阅读:(15) ⋅ 点赞:(0)


一、微服务概述

1.1 微服务架构特点

微服务架构是一种将单体应用程序拆分为多个小型服务的架构风格,每个服务都运行在自己的进程中,服务之间通过轻量级的通信机制(如 HTTP/REST、消息队列等)进行交互。它具有以下显著特点:

  • 服务拆分:遵循单一职责原则,每个微服务专注于完成一项特定的任务或功能,比如在电商系统中,将用户管理、商品管理、订单管理等功能拆分成独立的微服务,每个微服务负责自己的业务逻辑和数据存储,这样使得服务的功能单一,易于开发、维护和理解。
  • 独立部署:各个微服务可以独立进行部署、升级和扩展,互不影响。例如,当订单微服务的业务量增加时,可以单独对订单微服务进行扩展,而无需对整个系统进行调整,从而加快了业务迭代的速度,提高了系统的灵活性和可扩展性。
  • 去中心化:在微服务架构中,不存在一个统一的管理中心来控制所有服务,而是各个服务自治,每个服务可以根据自身的需求选择合适的技术栈、数据库等,这种去中心化的管理和治理方式,支持团队的敏捷性和创新。

1.2 微服务与单体架构对比

  • 优势
    • 可扩展性:微服务架构下每个服务可以根据负载进行单独扩展,比如在电商大促期间,可以针对订单服务和商品服务进行重点扩展,以应对高并发,而单体架构扩展时往往需要整体扩展,成本较高且效率较低。
    • 灵活性和敏捷性:各服务可采用不同技术栈,独立开发和部署,能快速响应业务变化,如用户服务可以用 Java 开发,搜索服务可以用 Python 结合 Elasticsearch 开发,而单体架构技术栈相对单一,修改和部署都较为复杂。
    • 故障隔离:某个微服务出现故障,理论上只会影响自身功能,不会导致整个系统瘫痪,比如支付微服务故障,不会影响用户浏览商品,而单体架构中一处错误可能引发整个系统崩溃。
    • 技术多样性:允许为不同服务选择最适合的框架、语言和工具,优化开发效率和性能 ,而单体架构技术选型较为统一,难以针对不同功能模块进行优化。
  • 挑战
    • 管理复杂性增加:服务数量增多,管理和协调变得更加复杂,需要处理服务间通信、服务发现、分布式事务等问题。
    • 分布式系统挑战:需要处理分布式系统的复杂性,如网络延迟、分布式事务等,确保数据一致性的难度较大。
    • 运维成本增加:每个服务都需要独立部署和监控,增加了运维成本,对运维人员的技术要求也更高。
  • 适用场景
    • 微服务架构:适用于大型、复杂、业务变化频繁、需要高可扩展性和灵活性的系统,如大型电商平台、社交网络平台等。
    • 单体架构:适用于小型项目、业务逻辑简单、开发周期短、资源有限的场景,比如一些小型的企业内部管理系统。

1.3 Spring Cloud 核心组件

Spring Cloud 是一系列框架的集合,它为微服务架构提供了丰富的组件,用于实现服务治理、配置管理、负载均衡等功能,以下是一些核心组件:
- Eureka:服务注册与发现组件,主要负责服务实例的注册和发现。微服务启动时会将自己注册到 Eureka Server 上,其他微服务通过 Eureka Server 获取服务实例列表,从而实现服务间的通信。Eureka Server 采用 CS 架构,并且具有自我保护机制,在网络分区等异常情况下,能保证服务的可用性。
- Ribbon:客户端负载均衡器,它与服务发现组件(如 Eureka)无缝集成,当一个微服务需要调用另一个微服务时,Ribbon 会从服务实例列表中选择一个合适的实例进行调用,提供了多种负载均衡策略,如轮询、随机、加权等,以提高系统的性能和可用性。
- Feign:声明式服务调用组件,基于接口的注解配置,让远程服务调用像调用本地方法一样简单。它集成了 Ribbon 的负载均衡功能,并且支持熔断器集成,在调用服务出现异常时可以进行容错处理。
- Gateway:API 网关,是微服务架构的统一入口,负责对外部请求进行路由转发、请求过滤、权限验证等操作 。它基于 Spring 5、Spring Boot 2 和 Project Reactor 等技术开发,采用异步非阻塞模型,性能优越,并且支持多种谓词和过滤器,能灵活地对请求进行处理。

二、服务注册与发现(Eureka/Nacos)

2.1 Eureka Server 搭建

Eureka Server 是服务注册与发现的核心组件,下面是搭建 Eureka Server 的详细步骤:

  1. 创建 Spring Boot 项目:使用 Spring Initializr 创建一个新的 Spring Boot 项目,在依赖选择中添加Spring Cloud Netflix Eureka Server依赖。如果是使用 Maven 项目,在pom.xml文件中添加以下依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.0</version> <!-- 根据实际情况调整版本 -->
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  1. 配置启动类:在启动类上添加@EnableEurekaServer注解,开启 Eureka Server 功能。例如:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
  1. 配置注册中心:在application.yml文件中配置 Eureka Server 的相关属性,比如端口号、服务名称、是否注册自己、是否获取注册表等。示例配置如下:
server:
  port: 8761 # Eureka Server端口

spring:
  application:
    name: eureka-server # 服务名称

eureka:
  instance:
    hostname: localhost # 主机名
  client:
    register-with-eureka: false # 不注册自己到Eureka Server
    fetch-registry: false # 不从Eureka Server获取服务列表
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # Eureka Server地址

完成上述配置后,启动 Eureka Server 应用,访问http://localhost:8761,如果看到 Eureka Server 的管理界面,说明搭建成功。

2.2 服务提供者开发

服务提供者是提供具体业务功能的微服务,需要将自身注册到 Eureka Server 并暴露接口,步骤如下:

  1. 创建 Spring Boot 项目:同样使用 Spring Initializr 创建项目,并添加Spring Cloud Netflix Eureka Client和Spring Boot Starter Web依赖。Maven 依赖配置如下:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 配置启动类:在启动类上添加@EnableEurekaClient注解(Spring Cloud 2020+ 版本默认启用服务发现功能,此注解可以省略),表示该服务是 Eureka 客户端,会向 Eureka Server 注册。例如:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}
  1. 配置服务注册信息:在application.yml中配置服务名称、Eureka Server 地址等信息,确保服务能够正确注册到 Eureka Server。示例配置:
server:
  port: 8081 # 服务提供者端口

spring:
  application:
    name: user-service # 服务名称

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/ # Eureka Server地址
  instance:
    prefer-ip-address: true # 使用IP地址注册
  1. 暴露接口:编写 Controller 类,定义对外提供服务的接口。例如,创建一个简单的用户服务接口:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @GetMapping("/users")
    public String getUsers() {
        return "User Service is running!";
    }
}

启动服务提供者应用,在 Eureka Server 的管理界面中可以看到user-service已经注册成功,这表明服务提供者已经成功将自身注册到 Eureka Server,并可以对外提供服务。

2.3 服务消费者开发

服务消费者通过 Eureka Server 获取服务提供者的实例列表,并使用RestTemplate+Ribbon进行服务调用,实现步骤如下:

  1. 创建 Spring Boot 项目:创建项目时添加Spring Cloud Netflix Eureka Client、Spring Boot Starter Web依赖,如果没有默认引入 Ribbon,还需要添加Spring Cloud Netflix Ribbon依赖(一般 Eureka Client 中已经包含 Ribbon 依赖)。Maven 依赖配置如下:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 配置启动类:启动类添加@EnableEurekaClient注解(同服务提供者,新版本可省略),开启 Eureka 客户端功能。示例代码:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
  1. 配置服务注册信息:在application.yml中配置服务名称和 Eureka Server 地址,与服务提供者类似。例如:
server:
  port: 8082 # 服务消费者端口

spring:
  application:
    name: order-service # 服务名称

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/ # Eureka Server地址
  1. 配置并使用 RestTemplate:在配置类中创建RestTemplate实例,并添加@LoadBalanced注解,使其具备负载均衡能力,能够与 Ribbon 结合使用。示例代码:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
  1. 调用服务:在 Controller 中注入RestTemplate,通过服务名调用服务提供者的接口。例如,订单服务调用用户服务获取用户信息:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/order/getUser")
    public String getUser() {
        String url = "http://user-service/users";
        return restTemplate.getForObject(url, String.class);
    }
}

通过以上步骤,服务消费者就可以通过 Eureka Server 发现服务提供者,并使用RestTemplate+Ribbon进行服务调用。

2.4 Nacos 整合

Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台,它可以将服务注册与配置中心的功能合二为一,以下是整合 Nacos 的步骤:

  1. 引入依赖:在 Spring Boot 项目的pom.xml文件中引入spring-cloud-starter-alibaba-nacos-discovery和spring-cloud-starter-alibaba-nacos-config依赖,用于服务注册和配置管理。示例依赖配置:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

同时,确保项目中引入了 Spring Cloud Alibaba 和 Spring Cloud 相关的依赖管理:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2023.0.1</version> <!-- 根据实际情况调整版本 -->
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.0</version> <!-- 根据实际情况调整版本 -->
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  1. 配置 Nacos Server 地址:在bootstrap.yml(优先于application.yml加载,用于获取 Nacos 配置)或application.yml文件中配置 Nacos Server 的地址、服务名等信息。如果使用bootstrap.yml,配置如下:
spring:
  application:
    name: product-service # 服务名称
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos Server地址
      config:
        server-addr: 127.0.0.1:8848 # Nacos Server地址
        file-extension: yaml # 配置文件格式
        prefix: ${spring.application.name} # 配置文件前缀,一般为服务名
  1. 启用服务注册与发现:在启动类上添加@EnableDiscoveryClient注解,启用服务注册与发现功能。例如:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}
  1. 使用 Nacos 配置中心(可选):如果需要使用 Nacos 作为配置中心,可以在 Nacos 控制台创建配置文件,配置文件的Data ID格式一般为 s p r i n g . a p p l i c a t i o n . n a m e − {spring.application.name}- spring.application.name{spring.profiles.active}.${file-extension},例如product-service-dev.yaml。在应用中,可以通过@Value注解或@ConfigurationProperties注解获取配置中心的配置。例如,在 Controller 中获取配置:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {
    @Value("${product.name}")
    private String productName;

    @GetMapping("/product/info")
    public String getProductInfo() {
        return "Product Name: " + productName;
    }
}

通过以上步骤,就完成了 Nacos 的整合,实现了服务注册与配置中心二合一的功能,在实际开发中可以大大提高开发效率和系统的可维护性。

三、服务调用与负载均衡

3.1 Feign 声明式服务调用

Feign 是一种声明式的 Web 服务客户端,它让服务调用变得更加简单和直观,开发者只需定义一个接口并使用注解来配置 HTTP 请求,Feign 会自动生成实现类来处理 HTTP 请求的发送和接收。

  1. 依赖导入:在服务消费者的pom.xml文件中添加spring-cloud-starter-openfeign依赖。例如:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 接口定义:创建一个 Feign 客户端接口,使用@FeignClient注解指定要调用的服务名称,接口中的方法使用 Spring MVC 风格的注解来定义请求的路径、方法和参数等信息。比如,订单服务调用用户服务获取用户信息,定义如下接口:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "user-service")
public interface UserFeignClient {
    @GetMapping("/users/{id}")
    String getUserById(@PathVariable("id") Long id);
}
  1. 参数传递:在 Feign 接口方法中,可以使用@PathVariable、@RequestParam、@RequestBody等注解来传递参数。其中,@PathVariable用于路径参数,@RequestParam用于查询参数,@RequestBody用于请求体参数 。例如:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "product-service")
public interface ProductFeignClient {
    @GetMapping("/products")
    String getProducts(@RequestParam("category") String category);

    @PostMapping("/products")
    String addProduct(@RequestBody Product product);
}

在上述代码中,getProducts方法通过@RequestParam传递category参数,addProduct方法通过@RequestBody传递Product对象作为请求体。使用时,在需要调用服务的地方注入 Feign 客户端接口,即可像调用本地方法一样调用远程服务。例如:

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;

@RestController
public class OrderController {
    @Autowired
    private UserFeignClient userFeignClient;

    @GetMapping("/order/{userId}")
    public String getOrderByUserId(@PathVariable Long userId) {
        String userInfo = userFeignClient.getUserById(userId);
        // 处理订单逻辑,结合用户信息等
        return "Order related to user: " + userInfo;
    }
}

3.2 Ribbon 负载均衡策略

Ribbon 是一个客户端负载均衡器,它与 Eureka 等服务发现组件紧密集成,为服务调用提供了负载均衡的功能,通过在客户端维护服务实例列表,并根据一定的策略选择合适的实例进行调用,从而提高系统的可用性和性能。

  • 默认策略:Ribbon 的默认负载均衡策略是ZoneAvoidanceRule(区域感知策略),在单区域环境下,它类似于轮询策略(RoundRobinRule) 。ZoneAvoidanceRule会综合考虑区域的可用性和实例的可用性,优先选择处于可用区域且负载较低的实例。例如,在一个包含多个数据中心(区域)的分布式系统中,它会避免选择那些整体性能较差或者网络不稳定的区域中的实例,而是从性能较好的区域中选择实例进行调用。
  • 自定义策略:如果默认策略不能满足业务需求,可以通过配置或代码方式自定义负载均衡策略。
    • 配置方式:在application.yml文件中,针对特定的服务进行策略配置。比如,要将user-service的负载均衡策略改为随机策略(RandomRule),配置如下:
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
  • 代码方式:创建一个配置类,定义IRule的 Bean 来指定负载均衡策略。例如,创建一个配置类来使用最少并发数策略(BestAvailableRule):
import com.netflix.loadbalancer.BestAvailableRule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RibbonConfig {
    @Bean
    public IRule ribbonRule() {
        return new BestAvailableRule();
    }
}

在上述代码中,BestAvailableRule会选择当前并发请求数最小的服务实例进行调用,适用于希望将请求分配到负载较轻实例的场景,通过这种方式可以根据实际业务场景灵活选择合适的负载均衡策略,优化服务调用的性能和可用性。

3.3 服务熔断与降级

在分布式系统中,服务之间存在依赖关系,当某个服务出现故障或响应超时,可能会导致级联故障,最终使整个系统崩溃,这就是所谓的 “服务雪崩”。为了防止这种情况发生,可以使用 Hystrix 来实现服务熔断与降级。

  1. Hystrix 整合:在项目中引入spring-cloud-starter-netflix-hystrix依赖。例如:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
  1. 启用 Hystrix:在启动类上添加@EnableHystrix注解,开启 Hystrix 功能。例如:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

@SpringBootApplication
@EnableHystrix
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  1. 服务熔断:Hystrix 通过断路器(Circuit Breaker)来实现服务熔断。当对某个服务的调用失败率达到一定阈值(默认是 50%),且在一定时间窗口(默认 10 秒)内请求数达到一定数量(默认 20 个)时,断路器会打开,后续对该服务的请求将不再实际调用,而是直接返回一个预设的 fallback 结果,快速失败,避免资源的无效消耗。例如,对一个调用用户服务的方法进行熔断配置:
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @HystrixCommand(commandProperties = {
            // 熔断触发的最小请求数,20个
            @com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
            // 熔断触发的错误百分比阈值,50%
            @com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
            // 熔断开启后的休眠时间窗,5秒
            @com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000")
    })
    public String getUserInfo(Long userId) {
        // 实际调用用户服务的逻辑
        // 例如通过Feign调用其他服务获取用户信息
    }
}
  1. 服务降级:当服务熔断或者服务调用出现异常(如超时、运行时异常等)时,会触发服务降级。通过定义 fallback 方法,在服务不可用时返回一个兜底的结果,保证系统的基本可用性 。例如,继续上面的例子,为getUserInfo方法添加 fallback 方法:
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @HystrixCommand(commandProperties = {
            @com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
            @com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
            @com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000")
    }, fallbackMethod = "getUserInfoFallback")
    public String getUserInfo(Long userId) {
        // 实际调用用户服务的逻辑
    }

    public String getUserInfoFallback(Long userId) {
        // 降级逻辑,返回默认信息或错误提示
        return "User service is currently unavailable, please try again later.";
    }
}

通过服务熔断与降级机制,可以有效地防止服务雪崩,提高系统的稳定性和容错性。

3.4 实战案例

下面通过一个基于 Spring Cloud 的用户 - 订单微服务调用案例,来巩固前面所学的知识,展示完整的微服务开发流程。

  1. 项目结构
  • eureka-server:服务注册中心,负责服务的注册与发现。
  • user-service:用户服务,提供用户相关的接口,如查询用户信息。
  • order-service:订单服务,处理订单相关业务,需要调用用户服务获取用户信息。
  1. 实现步骤
  • 搭建 Eureka Server:按照前面 “2.1 Eureka Server 搭建” 的步骤,创建 Eureka Server 项目,配置并启动,使其监听在8761端口。
  • 开发用户服务:依据 “2.2 服务提供者开发” 的内容,创建user-service项目,注册到 Eureka Server,暴露查询用户信息的接口。例如,创建UserController:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @GetMapping("/users/{id}")
    public String getUserById(@PathVariable Long id) {
        // 模拟从数据库或其他数据源获取用户信息
        return "User with id " + id + " information";
    }
}
  • 开发订单服务:参照 “2.3 服务消费者开发” 和 “3.1 Feign 声明式服务调用” 的步骤,创建order-service项目,注册到 Eureka Server,并使用 Feign 调用user-service。首先添加 Feign 依赖,然后创建 Feign 客户端接口UserFeignClient:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "user-service")
public interface UserFeignClient {
    @GetMapping("/users/{id}")
    String getUserById(@PathVariable("id") Long id);
}

接着在OrderController中注入UserFeignClient并调用:

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;

@RestController
public class OrderController {
    @Autowired
    private UserFeignClient userFeignClient;

    @GetMapping("/orders/{userId}")
    public String getOrderByUserId(@PathVariable Long userId) {
        String userInfo = userFeignClient.getUserById(userId);
        // 处理订单逻辑,结合用户信息创建订单等
        return "Order created for user: " + userInfo;
    }
}
  • 负载均衡与服务熔断降级:根据 “3.2 Ribbon 负载均衡策略” 和 “3.3 服务熔断与降级”,在order-service中配置 Ribbon 的负载均衡策略(如使用随机策略),并对调用user-service的方法添加 Hystrix 的熔断与降级配置。在application.yml中配置 Ribbon 策略:
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

在UserFeignClient接口对应的调用方法上添加 Hystrix 注解:

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "user-service")
public interface UserFeignClient {
    @GetMapping("/users/{id}")
    @HystrixCommand(fallbackMethod = "getUserByIdFallback")
    String getUserById(@PathVariable("id") Long id);

    default String getUserByIdFallback(Long id) {
        return "User service is unavailable, please try again later.";
    }
}

通过这个实战案例,完整地展示了 Spring Cloud 微服务中服务注册与发现、服务调用、负载均衡以及服务熔断降级的实现过程,有助于深入理解和掌握 Spring Cloud 微服务开发的核心技术。


网站公告

今日签到

点亮在社区的每一天
去签到