熔断场景
Spring Cloud Tencent CircuitBreaker 结合 Polaris 的熔断能力提供了标准的熔断实现,并提供服务级、接口级、节点级三种熔断级别,可以根据需求组合搭配,来实现期望的熔断效果。
本文介绍在本地开发 Java 应用,通过 Spring Cloud 的方式接入 TSE 治理中心(北极星网格),使用服务熔断功能。
前提条件
1. 在开始开发前,请确保您已经参见 下载 Maven下载安装了 Java 和 Maven。
2. 已创建 TSE 治理中心(北极星网格)实例,操作步骤详情参见 引擎管理。
操作步骤
步骤1:引入依赖
1.1 引入 spring cloud tencent 依赖
修改应用根目录下的 pom.xml,添加
dependencyManagement
:<dependencyManagement><dependencies><dependency><groupId>com.tencent.cloud</groupId><artifactId>spring-cloud-tencent-dependencies</artifactId><version>${version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
注意:
请根据项目 Spring Boot 和 Spring Framework 的版本,选择合适的 Spring Cloud Tencent 版本。
服务级熔断支持版本号大于1.10.0的 Spring Cloud Tencent 版本。
1.2 引入 spring cloud tencent starter
说明:
因为熔断能力依赖服务发现能力,所以需要主调方和被调方都引入服务注册与发现依赖。
方式一:只引入
spring-cloud-starter-tencent-polaris-circuitbreaker
。<dependency><groupId>com.tencent.cloud</groupId><artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId></dependency>
方式二:通过
spring-cloud-starter-tencent-all
引入 sct 所有 starters。<dependency><groupId>com.tencent.cloud</groupId><artifactId>spring-cloud-starter-tencent-all</artifactId><!-- 注意需要指定 type=pom--><type>pom</type></dependency>
如果使用 Spring Cloud 2020 及以后版本,还需要添加如下依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency>
步骤2:增加相关配置文件并设置熔断方法
Spring Cloud Tencent 支持 Feign、RestTemplate、WebClient、Spring Cloud Gateway 四种组件的熔断,并会自动拉取您在北极星上为被调服务配置的熔断规则进行熔断。选择您适合的方式配置即可。
1. 添加 Feign 依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
2. 添加 Feign 配置文件
spring:application:name: polaris-circuitbreaker-feign-examplecloud:openfeign:circuitbreaker:enabled: truepolaris:address: grpc://${修改为 Polaris 服务地址}:8091namespace: defaultenabled: trueloadbalancer:enabled: truecircuitbreaker:enabled: true
3. 设置 Feign 熔断方法
声明 Feign 调用
当 Feign fallback 不配置时,会在熔断发生时,从 polaris server 拉取降级配置,进行降级,降级的 response body 会序列化成您在 Feign 中配置的返回对象,请确保能正确的序列化。
@Primary@FeignClient(name = "polaris-circuitbreaker-callee-service", fallback = ProviderBFallback.class)public interface ProviderB {/*** Get info of service B.** @return info of service B*/@GetMapping("/example/service/b/info")String info();}
声明本地 Feign 熔断方法(可选)
@Componentpublic class ProviderBFallback implements ProviderB {@Overridepublic String info() {return "fallback: trigger the refuse for service b";}}
发起 Feign 调用
@RestController@RequestMapping("/example/service/a")public class ServiceAController {@Autowiredprivate ProviderB polarisServiceB;/*** Get info of Service B by Feign.* @return info of Service B*/@GetMapping("/getBServiceInfo")public String getBServiceInfo() {return polarisServiceB.info();}
1. 添加 RestTemplate 配置文件
spring:application:name: polaris-circuitbreaker-resttemplate-examplecloud:polaris:address: grpc://${修改为 Polaris 服务地址}:8091namespace: defaultenabled: trueloadbalancer:enabled: truecircuitbreaker:enabled: true
2. 设置 RestTemplate 熔断方法
设置 RestTemplate bean,添加
@PolarisCircuitBreaker
注解。@Bean@LoadBalanced@PolarisCircuitBreakerpublic RestTemplate restTemplate() {DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service");RestTemplate restTemplate = new RestTemplate();restTemplate.setUriTemplateHandler(uriBuilderFactory);return restTemplate;}
说明:
@PolarisCircuitBreaker 包含两个参数:
String 类型的 fallback 表示返回希望降级的
response body string
;PolarisCircuitBreakerFallback
类型的 fallbackClass
表示返回希望降级的具体 response
,需要自定义实现 PolarisCircuitBreakerFallback#fallback()
方法,返回 PolarisCircuitBreakerHttpResponse
。两个参数不能同时配置。 当
@PolarisCircuitBreaker
不配置任何参数时,会在熔断发生时,从 polaris server 拉取降级配置,进行降级,降级的 response body 会序列化成您在 RestTemplate 中配置的返回对象,请确保能正确的序列化。3. 发起 RestTemplate 调用
@RestController@RequestMapping("/example/service/a")public class ServiceAController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/getBServiceInfo")public String getBServiceInfo() {return restTemplateFallbackFromPolaris.getForEntity("/example/service/b/info", String.class);}}
1. 添加 WebFlux 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>
2. 设置 WebClient 配置文件
spring:application:name: polaris-circuitbreaker-webclient-examplecloud:polaris:address: grpc://${修改为 Polaris 服务地址}:8091namespace: defaultenabled: trueloadbalancer:enabled: truecircuitbreaker:enabled: true
3. 设置 WebClient 熔断方法
设置 WebClient bean
@LoadBalanced@BeanWebClient.Builder webClientBuilder() {return WebClient.builder().baseUrl("http://polaris-circuitbreaker-callee-service");}
发起 WebClient 调用
@RestController@RequestMapping("/example/service/a")public class ServiceAController {@Autowiredprivate ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;@Autowiredprivate WebClient.Builder webClientBuilder;@GetMapping("/getBServiceInfo")public Mono<String> getBServiceInfo() {return webClientBuilder.build().get().uri("/example/service/b/info").retrieve().bodyToMono(String.class).transform(it ->reactiveCircuitBreakerFactory// create 的参数为被调服务的服务名.create("polaris-circuitbreaker-callee-service")// 熔断降级方法.run(it, throwable -> Mono.just("fallback: trigger the refuse for service b")));}}
1. 添加 Spring Cloud Gateway 依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
2. 设置 Spring Cloud Gateway 配置文件
以 gateway.discovery.locator 形式配置
spring:application:name: GatewayScgServicecloud:polaris:address: grpc://${修改为 Polaris 服务地址}:8091namespace: defaultenabled: truegateway:discovery:locator:enabled: true'predicates[0]':name: Pathargs:patterns: '''/'' + serviceId + ''/**''''filters[0]':name: RewritePathargs:regexp: '''/'' + serviceId + ''/(?<remaining>.*)'''replacement: '''/$\\{remaining}''''filters[1]':# 配置熔断 Filtername: CircuitBreakerargs:# statusCodes,可选参数,配置熔断的匹配返回码,缺省时会自动识别 "5**" 为错误,可以为"4**,5**"的形式,也可以为具体的返回码statusCodes: '''404,5**'''# fallbackUri,可选参数,配置熔断降级的转发路由方法,缺省时会在熔断触发后拉取 plaris server 配置的降级作为 responsefallbackUri: '''forward:/polaris-fallback'''
以普通路由形式配置形式配置
spring:application:name: GatewayScgServicecloud:polaris:address: grpc://${修改为 Polaris 服务地址}:8091namespace: defaultenabled: truegateway:routes:- id: polaris-circuitbreaker-callee-serviceuri: lb://polaris-circuitbreaker-callee-servicepredicates:- Path=/polaris-circuitbreaker-callee-service/**
3. 设置 Spring Cloud Gateway 熔断方法
设置熔断降级的转发路由方法
@RestControllerpublic class FallbackController {@GetMapping("/polaris-fallback")Mono<String> getFallback() {return Mono.just("fallback: trigger the refuse for service b");}}
步骤3:验证
为了验证熔断能力,被调端至少启动两个实例,一个返回成功,一个返回失败。
测试主调方向被调方发起服务调用,前几个请求会出现往有问题的服务发起调用,当问题数达到您在北极星控制台配置的熔断阈值时,即会触发熔断,主调方不再发起调用,直接返回熔断降级方法。