本文介绍了Sentinel与Feign的集成,重点讲解了如何通过Sentinel实现Feign熔断保护,确保服务间的稳定调用。Sentinel提供了多种流量控制和熔断策略,能够有效防止服务故障扩散,保证系统的稳定性。文章详细阐述了Sentinel与Feign的环境搭建步骤以及具体的应用场景,帮助读者全面理解sentinel+Feign熔断学习。
Sentinel与Feign基础介绍 Sentinel简介Sentinel 是阿里巴巴开源的一款轻量级的、高性能的、分布式的流量控制组件。它能够对微服务中的各种流量进行控制,包括流量入口、流量过滤、流量整形、流量路由等功能。Sentinel 提供了丰富的流控规则,可以针对不同的资源进行流量控制,并支持多种流控模式,如链路模式、系统模式和API模式等。Sentinel 的设计初衷是为了保护后端系统免受流量洪峰的冲击,通过实时监控和流量控制,确保系统的稳定运行。
Sentinel 的主要特性包括:
- 实时监控:提供实时监控功能,能够实时查看系统各个资源的调用情况。
- 流量控制:支持多种流控策略,包括链路模式、系统模式和API模式等。
- 灵活规则配置:支持动态配置控制规则,可以通过控制台直接修改规则配置。
- 轻量级、高性能:Sentinel 设计轻量,对系统影响小,能够适应高并发场景。
Feign 是一个声明式的 Web 服务客户端,它使得编写 Web 服务客户端变得更加简单。Feign 的目的是让编写 Web 服务客户端变得和编写一个 Java 方法一样简单。Feign 的开发模式是基于接口注解,它允许开发者定义接口并通过注解的方式来调用服务。Feign 自动处理 HTTP 请求、响应编码、解码等,并且支持多个 HTTP 客户端,如 HTTP Client、Netty、OkHttp 等。
Feign 的主要特性包括:
- 声明式接口调用:通过定义接口并添加注解,来实现服务的调用。
- 集成多种 HTTP 客户端:支持 HTTP Client、Netty、OkHttp 等 HTTP 客户端。
- 自动处理 HTTP 请求:Feign 自动处理 HTTP 请求、响应编码、解码等。
- 与 Spring Cloud 集成:Feign 可以和 Spring Cloud 集成,实现服务发现。
Sentinel 与 Feign 的集成能够实现服务间的熔断保护。当调用链路中的某个微服务实例出现故障,或者调用量激增、吞吐量下降时,Sentinel 可以针对性地采取流量控制策略,防止故障扩散。Sentinel 通过 Feign 提供的接口注解来实现对服务接口的流量控制和熔断保护。
以下是 Sentinel 与 Feign 集成的基本流程:
- 定义服务接口并添加注解。
- 引入 Sentinel 依赖。
- 配置 Sentinel 规则。
- 在 Feign 客户端中使用 Sentinel 进行流量控制。
开发环境搭建主要包括 JDK、Spring Boot、Spring Cloud 以及 Sentinel、Feign 的依赖引入。这里假设你已经安装好了 JDK 和 Maven,接下来需要搭建 Spring Boot 项目,并引入 Sentinel 和 Feign 的依赖。
- 创建一个新的 Spring Boot 项目。
- 在
pom.xml
文件中添加依赖。
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Feign Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Spring Cloud Starter Netty -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Sentinel Starter -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Sentinel Datasource -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-consul</artifactId>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Sentinel与Feign环境搭建步骤
安装Sentinel控制台
Sentinel 控制台是一个图形化的界面,可以用来查看实时监控数据以及配置控制规则。
1. 下载并安装Sentinel控制台
git clone https://github.com/alibaba/Sentinel-Dashboard.git
cd Sentinel-Dashboard
mvn clean package -DskipTests
2. 启动Sentinel控制台
java -jar target/sentinel-dashboard-1.8.2.jar --server.port=8080
配置Sentinel
1. 在Spring Boot项目中添加Sentinel相关配置
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # 配置Sentinel Dashboard地址
port: 8719 # 配置Gateway端口
2. 添加Feign客户端
在 Spring Boot 项目中添加 Feign 客户端依赖,并在主类上添加注解启用 Feign 服务。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3. 定义Feign客户端接口
定义 Feign 客户端接口,并添加注解 @FeignClient
。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "paymentService")
public interface PaymentService {
@GetMapping("/pay")
String pay();
}
通过实例代码解析Sentinel与Feign集成
在主类中添加 @EnableCircuitBreaker
注解启用熔断器。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
配置Sentinel规则
在 application.yml
文件中配置 Sentinel 规则。
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # 配置Sentinel Dashboard地址
port: 8719 # 配置Gateway端口
custom-rules:
- resource: "paymentService"
count: 2 # 最大并发量
strategy: 0 # 链路模式
timeoutMs: 5000 # 超时时间
maxDurationMs: 60000 # 最大等待时间
degradeTimeMs: 5000 # 慢调用比率阈值
slowRatioThreshold: 0.2
Sentinel的熔断机制原理
熔断概念
熔断机制是一种处理网络故障的机制。当服务调用链路中的某个服务出现故障时,服务调用方会进行熔断保护,不再进行请求调用,而是直接返回错误信息。熔断机制可以有效地避免故障扩散,保护系统稳定性。
熔断机制的工作原理如下:
- 正常调用:初始状态,服务调用正常,没有出现异常情况。
- 异常调用:服务调用出现异常(如超时、抛出异常等)时,熔断计数器开始计数。
- 熔断打开:熔断计数器达到阈值时,熔断器会打开,不再调用有问题的服务,而是直接返回错误信息。
- 半打开:经过一段时间后(即超时时间
halfOpenPeriod
),熔断器会进入半打开状态,允许少量请求通过。 - 熔断恢复:如果在半打开状态下的请求恢复正常,则熔断器恢复到正常调用状态;否则熔断器继续保持打开状态。
Sentinel 提供了丰富的熔断规则,包括链路模式、系统模式和 API 模式等。
链路模式(Link Mode)
链路模式用于保护服务之间的调用链路。当调用链路中某个服务实例出现故障时,会通过熔断降级的方式来隔离故障服务,从而防止故障的扩散。
1. 链路模式的熔断设置
配置链路模式的熔断规则:
custom-rules:
- resource: "链路名称"
count: 2 # 最大并发量
strategy: 0 # 链路模式
timeoutMs: 5000 # 超时时间
maxDurationMs: 60000 # 最大等待时间
degradeTimeMs: 5000 # 慢调用比率阈值
slowRatioThreshold: 0.2
2. 链路模式的熔断状态
链路模式的熔断状态包括正常状态、半打开状态和打开状态。
- 正常状态:熔断器未开启,直接调用服务。
- 打开状态:当熔断器打开时,直接返回错误信息,不再调用服务。
- 半打开状态:当熔断器处于半打开状态时,允许部分请求通过,如果请求恢复正常,则会关闭熔断器。
系统模式(System Mode)
系统模式用于保护系统的整体稳定性。当系统的负载超过一定阈值时,会自动开启熔断机制,防止系统过载。
1. 系统模式的熔断设置
配置系统模式的熔断规则:
custom-rules:
- resource: "系统名称"
count: 2 # 最大并发量
strategy: 1 # 系统模式
timeoutMs: 5000 # 超时时间
maxDurationMs: 60000 # 最大等待时间
degradeTimeMs: 5000 # 慢调用比率阈值
degradeMaxRequestCount: 10 # 最大请求数
2. 系统模式的熔断状态
系统模式的熔断状态包括正常状态、打开状态和半打开状态。
- 正常状态:熔断器未开启,直接调用服务。
- 打开状态:当熔断器打开时,直接返回错误信息,不再调用服务。
- 半打开状态:当熔断器处于半打开状态时,允许部分请求通过,如果请求恢复正常,则会关闭熔断器。
API 模式(API Mode)
API 模式用于保护 API 接口的调用。当 API 接口的调用出现异常时,会通过熔断降级的方式来隔离故障服务,从而防止故障的扩散。
1. API 模式的熔断设置
配置 API 模式的熔断规则:
custom-rules:
- resource: "接口名称"
count: 2 # 最大并发量
strategy: 2 # API 模式
timeoutMs: 5000 # 超时时间
maxDurationMs: 60000 # 最大等待时间
degradeTimeMs: 5000 # 慢调用比率阈值
slowRatioThreshold: 0.2
2. API 模式的熔断状态
API 模式的熔断状态包括正常状态、打开状态和半打开状态。
- 正常状态:熔断器未开启,直接调用服务。
- 打开状态:当熔断器打开时,直接返回错误信息,不再调用服务。
- 半打开状态:当熔断器处于半打开状态时,允许部分请求通过,如果请求恢复正常,则会关闭熔断器。
熔断机制的基本原理是通过监控服务调用的链路和系统负载来判断是否需要熔断。当服务调用链路中的某个服务实例出现故障,或者系统的负载超过一定阈值时,会自动开启熔断机制,防止故障扩散。熔断机制通过设置超时时间、最大请求数和慢调用比率等参数来控制熔断器的状态。
- 正常状态:初始状态,服务调用正常,没有出现异常情况。
- 异常状态:服务调用出现异常时,熔断计数器开始计数。
- 熔断打开状态:熔断计数器达到阈值时,熔断器会打开,不再调用有问题的服务,而是直接返回错误信息。
- 半打开状态:经过一段时间后(即超时时间
halfOpenPeriod
),熔断器会进入半打开状态,允许少量请求通过。 - 熔断恢复状态:如果在半打开状态下的请求恢复正常,则熔断器恢复到正常调用状态;否则熔断器继续保持打开状态。
Feign 与 Spring Cloud 的集成可以让开发者更加方便地进行服务间的调用。Spring Cloud Feign 提供了一种声明式的 Web 服务客户端,使得服务调用更加简单。
1. 添加依赖
在 pom.xml
文件中添加 Feign 依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 启用 Feign 客户端
在主类上添加 @EnableFeignClients
注解启用 Feign 客户端。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3. 定义 Feign 接口
定义一个 Feign 接口,并添加 @FeignClient
注解,指定服务名称。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "paymentService")
public interface PaymentService {
@GetMapping("/pay")
String pay();
}
Sentinel熔断规则在Feign中的应用
Sentinel 与 Feign 的集成可以在 Feign 接口中直接配置熔断规则。
1. 添加依赖
在 pom.xml
文件中添加 Sentinel 依赖。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2. 配置 Sentinel 规则
在 application.yml
文件中配置 Sentinel 规则。
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # 配置Sentinel Dashboard地址
port: 8719 # 配置Gateway端口
custom-rules:
- resource: "paymentService"
count: 2 # 最大并发量
strategy: 0 # 链路模式
timeoutMs: 5000 # 超时时间
maxDurationMs: 60000 # 最大等待时间
degradeTimeMs: 5000 # 慢调用比率阈值
slowRatioThreshold: 0.2
3. 实例代码解析
定义一个 Feign 接口,并配置熔断规则。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "paymentService")
public interface PaymentService {
@GetMapping("/pay")
String pay();
}
然后在主类中添加 @EnableCircuitBreaker
注解启用熔断器。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
测试与验证
测试环境构建
搭建测试环境需要创建两个服务,分别是服务提供者和消费者。
1. 创建服务提供者
创建一个简单的服务提供者,提供支付接口。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
@GetMapping("/pay")
public String pay() {
return "Payment successful";
}
}
2. 创建服务消费者
创建一个服务消费者,调用服务提供者提供的支付接口,并配置熔断规则。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@FeignClient(name = "paymentService")
public interface PaymentService {
@GetMapping("/pay")
String pay();
}
}
通过模拟异常请求验证熔断机制
在服务提供者中引入异常,模拟服务故障。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
@GetMapping("/pay")
public String pay() {
if (Math.random() > 0.8) {
throw new RuntimeException("Service is down");
}
return "Payment successful";
}
}
测试结果分析与优化建议
测试结果分析
通过模拟异常请求,可以看到服务消费者在服务提供者出现异常时,会触发熔断机制,不再调用服务,而是直接返回错误信息。
优化建议
- 增加熔断阈值:根据业务场景,适当调整熔断器的阈值。
- 增加重试机制:在服务调用失败时,增加重试机制,提高服务的可用性。
- 增加监控:通过 Sentinel 的监控功能,实时监控服务的调用情况。
假设有一个电商系统,其中包含订单服务和支付服务。订单服务调用支付服务进行支付操作。
1. 创建订单服务
创建一个简单的订单服务,调用支付服务。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
@FeignClient(name = "paymentService")
public interface PaymentService {
@GetMapping("/pay")
String pay();
}
}
2. 创建支付服务
创建一个简单的支付服务,提供支付接口。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class PaymentServiceApplication {
public static void main(String[] args) {
SpringApplication.run(PaymentServiceApplication.class, args);
}
@GetMapping("/pay")
public String pay() {
return "Payment successful";
}
}
案例分析与说明
在电商系统中,订单服务调用支付服务进行支付操作。当支付服务出现异常时,订单服务会触发熔断机制,不再调用支付服务,而是直接返回错误信息。
1. 服务调用链路
订单服务通过 Feign 客户端调用支付服务,调用链路如下:
- 订单服务调用支付服务。
- 支付服务返回支付结果。
- 订单服务根据支付结果进行后续操作。
2. 熔断机制
当支付服务出现异常时,订单服务会触发熔断机制,不再调用支付服务,而是直接返回错误信息。熔断机制可以有效地避免故障扩散,保护系统的稳定性。
典型应用场景介绍场景一:电商系统
在电商系统中,订单服务调用支付服务进行支付操作。当支付服务出现异常时,订单服务会触发熔断机制,不再调用支付服务,而是直接返回错误信息。
场景二:金融系统
在金融系统中,交易服务调用风控服务进行风险控制。当风控服务出现异常时,交易服务会触发熔断机制,不再调用风控服务,而是直接返回错误信息。
场景三:物流系统
在物流系统中,订单服务调用配送服务进行配送操作。当配送服务出现异常时,订单服务会触发熔断机制,不再调用配送服务,而是直接返回错误信息。
场景四:游戏系统
在游戏系统中,充值服务调用支付服务进行支付操作。当支付服务出现异常时,充值服务会触发熔断机制,不再调用支付服务,而是直接返回错误信息。
通过 Sentinel 与 Feign 的集成,可以有效地保护系统的稳定性,防止故障扩散。