本文详细介绍了Sentinel与Feign熔断资料,包括Sentinel的流量控制、熔断降级和系统保护功能,以及如何将Sentinel与Feign集成以提供更强大的保护机制。文章还探讨了Feign中的熔断实现和Sentinel中的熔断规则配置,并通过实际案例展示了如何使用Sentinel保护Feign调用。
Sentinel介绍 Sentinel是什么Sentinel 是阿里巴巴开源的一款高可用的流量控制组件,它能够根据预设的规则动态地对系统流量进行控制,从而达到保护系统的目的。Sentinel 能够与各种编程语言和框架相融合,为微服务架构下的应用提供流量控制、降级、系统负载保护等功能。
Sentinel 支持多个维度的流量控制,如:
- 资源维度:可以针对具体的方法、接口、RPC 调用等进行控制。
- 来源维度:可以针对特定的 IP、用户等进行限制。
- 依赖维度:可以针对依赖的接口进行控制。
Sentinel 提供了多个核心功能,包括但不限于:
- 流量控制:在系统流量超过设定阈值时,自动进行流量控制,避免系统过载。
- 熔断降级:在调用链路的某个资源,实际系统高达一定慢调用比例时,直接切断调用链路,避免影响其他资源;在系统负载较高时,降低系统负载,提升系统可用性。
- 系统负载保护:系统在高负载时自动减少流入流量,从而降低系统的压力,保护系统稳定运行。
- 热点参数防护:对经常被访问的热点参数进行控制,防止对热点参数的压力过大导致系统崩溃。
Feign 是一个声明式的 Web 服务客户端,它使得编写 Web 服务客户端变得更加简单。Feign 可以与 Spring Cloud 结合使用,简化微服务之间的调用。
Feign 的主要特性包括:
- 声明式调用:开发者可以通过简单的注解形式来定义 HTTP 请求,而无需手动编写 HTTP 请求代码。
- 集成 Ribbon 和 Hystrix:Feign 可以与 Ribbon 和 Hystrix 集成,实现负载均衡和熔断功能。
- 支持多种注解:Feign 支持多种注解,如
@FeignClient
、@RequestMapping
、@GetMapping
、@PostMapping
等。
创建 Feign 客户端
以下是一个简单的示例代码,展示了如何创建一个 Feign 客户端来调用一个微服务。
首先,引入 Feign 相关的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
然后,在主启动类上添加 @EnableFeignClients
注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
接着,定义一个 Feign 客户端接口:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "example-service", url = "http://example-service.com")
public interface ExampleClient {
@GetMapping("/example")
String getExample(@RequestParam("param1") String param1, @RequestParam("param2") String param2);
}
最后,在需要调用该接口的地方注入该接口,并调用方法:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ExampleService {
private final ExampleClient exampleClient;
@Autowired
public ExampleService(ExampleClient exampleClient) {
this.exampleClient = exampleClient;
}
public String callExampleService(String param1, String param2) {
return exampleClient.getExample(param1, param2);
}
}
Sentinel与Feign的集成
Sentinel与Feign集成的原因
Sentinel 与 Feign 的集成可以为微服务之间的调用提供更强大的保护机制。通过集成,Sentinel 可以对 Feign 调用进行细粒度的流量控制、熔断降级和系统负载保护,从而提升整个系统的健壮性和稳定性。
Sentinel 可以与 Feign 结合使用,以提供以下功能:
- 流量控制:对 Feign 客户端的调用进行流量控制,避免调用过载。
- 熔断降级:在依赖调用失败率高时,自动进行熔断降级。
- 系统保护:当系统负载过高时,减少流入流量,保护系统稳定运行。
Sentinel 与 Feign 的集成主要通过自定义的 Feign
客户端处理器实现。
首先,引入 Sentinel 和 Feign 的依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
然后,在主应用类中启用 Feign 客户端和 Sentinel:
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);
}
}
接下来,自定义 Feign
客户端处理器,使用 Sentinel
对 Feign 调用进行保护:
import com.alibaba.cloud.sentinel.feign.SentinelFeign;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import feign.RequestInterceptor;
import feign.RequestLine;
import feign.Retryer;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
@Component
public class CustomFeignClient {
private final ExampleClient exampleClient;
public CustomFeignClient() {
exampleClient = Feign.builder()
.client(new OkClient())
.encoder(new SpringFormEncoder(new SpringEncoder()))
.decoder(new SpringDecoder())
.options(new Request.Options(1000, 1000))
.retryer(new Retryer.Default())
.target(ExampleClient.class, "http://example-service.com");
}
public ExampleClient getExampleClient() {
return exampleClient;
}
}
@FeignClient(name = "example-service", url = "http://example-service.com")
public interface ExampleClient {
@GetMapping("/example")
@SentinelResource(value = "exampleApi", blockHandler = "handleBlock")
String getExample(@RequestParam("param1") String param1, @RequestParam("param2") String param2);
default Object handleBlock(BlockException ex) {
return "Blocked by Sentinel";
}
}
在上述代码中,@SentinelResource
注解用于标记需要 Sentinel 保护的 Feign 调用接口。blockHandler
方法用于处理被 Sentinel 断路的情况。
熔断机制是一种在系统负载过高或依赖服务出现故障时,自动将请求流量进行控制,避免进一步加重系统的负担。熔断机制通常包括以下步骤:
- 熔断(Circuit Breaker):当依赖调用失败率达到阈值时,系统会自动断开调用链路,停止向依赖服务发送请求。
- 半开(Half-Open):经过一段时间后,系统会自动尝试恢复调用,如果恢复成功,则继续正常调用,否则继续维持断开状态。
- 闭合(Closed):当依赖服务恢复正常后,系统会重新闭合调用链路,恢复正常调用。
熔断机制可以大大减少依赖服务故障对整个系统的影响,提高系统的可用性和稳定性。
Feign中的熔断实现Feign 通常与 Hystrix 集成来实现熔断功能。Hystrix 是 Netflix 开源的一个用于处理分布式系统中延迟和容错的库。它通过隔离依赖服务与服务间的交互,来提升复杂系统中各依赖之间的韧性,防止雪崩效应。
为了使用 Hystrix 实现 Feign 的熔断功能,需要引入 Hystrix 和 Feign 的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
然后,在 Feign 客户端接口中使用 @HystrixCommand
注解来定义熔断逻辑:
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import feign.Param;
import feign.RequestLine;
import feign.Retryer;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(name = "example-service", url = "http://example-service.com")
public interface ExampleClient {
@GetMapping("/example")
@HystrixCommand(groupKey = "exampleGroup", fallback = "fallbackMethod")
String getExample(@RequestParam("param1") String param1, @RequestParam("param2") String param2);
default String fallbackMethod() {
return "Fallback response";
}
}
在上述代码中,@HystrixCommand
注解用于定义熔断逻辑,groupKey
参数表示熔断的分组,fallback
方法用于定义熔断后的回调逻辑。
Sentinel 也提供了丰富的熔断规则,包括但不限于以下几种:
- RT(平均响应时间):当资源的平均响应时间超过阈值时,触发熔断。
- 异常比例:当资源的成功率为低于阈值时,触发熔断。
- 异常数:当一定时间内发生异常请求数超过阈值时,触发熔断。
Sentinel 的熔断规则可以在控制台上进行配置,也可以通过编程方式定义。
如何配置Sentinel熔断规则Sentinel 的熔断规则可以通过编程方式来定义,以下是一个简单的示例代码:
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import java.util.ArrayList;
import java.util.Collections;
public class SentinelRuleConfig {
public static void init() {
ArrayList<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("exampleApi");
rule.setCount(10);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
在上述代码中,FlowRule
用于定义一个熔断规则,setResource
方法用于设置资源名称,setCount
方法用于设置阈值,setGrade
方法用于设置熔断类型,setLimitApp
方法用于设置限流应用。
FlowRuleManager.loadRules
用于加载熔断规则。
FlowRule
的 setGrade
方法可以设置不同的熔断类型:
RuleConstant.FLOW_GRADE_QPS
:表示按照 QPS(每秒请求数)进行熔断。RuleConstant.FLOW_GRADE_RT
:表示按照 RT(平均响应时间)进行熔断。RuleConstant.FLOW_GRADE_EXCEPTION_RATIO
:表示按照异常比例进行熔断。RuleConstant.FLOW_GRADE_EXCEPTION_COUNT
:表示按照异常次数进行熔断。
假设存在一个电商平台系统,系统中存在一个商品服务和一个订单服务。商品服务负责商品信息的查询,订单服务负责订单信息的处理。在高并发场景下,如果订单服务出现问题,会影响到整个电商平台的可用性。
为了保护订单服务,可以使用 Sentinel 对商品服务中的订单服务调用进行熔断保护。
如何使用Sentinel保护Feign调用在商品服务中,可以通过 Sentinel 对调用订单服务的 Feign 客户端接口进行熔断保护。
首先,引入 Sentinel 和 Feign 的依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
然后,在订单服务的 Feign 客户端接口中使用 @SentinelResource
注解:
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
import feign.Retryer;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(name = "order-service", url = "http://order-service.com")
public interface OrderClient {
@GetMapping("/order")
@SentinelResource(value = "orderApi", blockHandler = "handleBlock")
String getOrder(@RequestParam("orderId") String orderId);
default String handleBlock(BlockException ex) {
return "Order service is unavailable";
}
}
在上述代码中,@SentinelResource
注解用于标记需要 Sentinel 保护的 Feign 调用接口,blockHandler
方法用于处理被 Sentinel 断路的情况。
接下来,在应用启动时,初始化 Sentinel 的熔断规则:
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import java.util.ArrayList;
import java.util.Collections;
public class SentinelRuleConfig {
public static void init() {
ArrayList<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("orderApi");
rule.setCount(10);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
在上述代码中,FlowRule
用于定义一个熔断规则,setResource
方法用于设置资源名称,setCount
方法用于设置阈值,setGrade
方法用于设置熔断类型,setLimitApp
方法用于设置限流应用。
FlowRuleManager.loadRules
用于加载熔断规则。
通过上述配置,当订单服务的响应时间过长或请求失败率过高时,Sentinel 会自动触发熔断机制,从而保护整个系统不受订单服务的影响。
总结,Sentinel 与 Feign 的集成,可以为微服务架构下的应用提供强大的流量控制、熔断降级和系统负载保护功能,从而提升系统的健壮性和稳定性。