Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护, 在构造 RestTemplate Bean的时候需要加上@SentinelRestTemplate注解。
整合RestTemplate
第一步: 创建 Spring Boot web应用工程,编写pom.xml配置文件:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
第二步:编写启动类和 RestTemplate 配置 :
@EnableDiscoveryClient
@SpringBootApplication
public class RestTemplateApplication {
public static void main(String[] args) {
SpringApplication.run(RestTemplateApplication.class, args);
}
}
@Configuration
public class WebConfig {
@Bean
@SentinelRestTemplate(fallback = "fallback", fallbackClass = ExceptionUtil.class, blockHandler="handleException",blockHandlerClass=ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
- blockHandlerClass:限流后处理的类
- blockHandler: 限流后处理的方法
- fallbackClsss:熔断后处理的类
- fallback:熔断后处理的方法
@SentinelRestTemplate 注解的属性支持限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)的处理。
其中 blockHandler 或 fallback 属性对应的方法必须是对应 blockHandlerClass 或 fallbackClass 属性中的静态方法。
该方法的参数跟返回值跟 org.springframework.http.client.ClientHttpRequestInterceptor#interceptor 方法一致,其中参数多出了一个 BlockException 参数用于获取 Sentinel 捕获的异常。
我们这里统一放在一个异常工具类处理(后期可根据具体项目修改返回值数据)
public class ExceptionUtil {
/**
* 限流后处理方法
* @param request
* @param body
* @param execution
* @param ex
* @return
*/
public static SentinelClientHttpResponse handleException(HttpRequest request,
byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
System.err.println("block: " + ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse("custom block info");
}
/**
* 熔断后处理的方法
* @param request
* @param body
* @param execution
* @param ex
* @return
*/
public static SentinelClientHttpResponse fallback(HttpRequest request,
byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
System.err.println("fallback: " + ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse("custom fallback info");
}
}
@SentinelRestTemplate 注解的限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)属性不强制填写。
当使用 RestTemplate 调用被 Sentinel 熔断后,会返回 RestTemplate request block by sentinel 信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 SentinelClientHttpResponse 用于构造返回信息。
若我们在开发期间,不希望Sentinel对服务提供者的接口进行容错,可以通过以下配置进行开关:
开启或关闭@SentinelRestTemplate注解:
resttemplate:
sentinel:
enabled: true
Sentinel实现与RestTemplate整合的相关源码:
org.springframework.cloud.alibaba.sentinel.custom.SentinelBeanPostProcessor