标签:mamicode -o 服务提供者 异常类 return 自动 逻辑 并且 ash
通用资源保护
引入依赖
需要注意SpringCloud-Alibaba与SpringCloud的版本关系
父工程引入 alibaba实现的SpringCloud
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
子工程中引入 sentinel
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
( 3) 配置熔断降级方法
@SentinelResource(value="orderFindById",blockHandler = "orderBlockHandler",fallback = "orderFallback") @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET) public Product findById(@PathVariable Long id) { if(id != 1) { throw new RuntimeException("错误"); } return restTemplate.getForObject("http://service-product/product/1",Product.class); } /** * 定义降级逻辑 * hystrix和sentinel * 熔断执行的降级方法 * 抛出异常执行的降级方法 */ public Product orderBlockHandler(Long id) { Product product = new Product(); product.setProductName("触发熔断的降级方法"); return product; } public Product orderFallback(Long id) { Product product = new Product(); product.setProductName("抛出异常执行的降级方法"); return product; }
@SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource
注解包含以下属性:
value
:资源名称,必需项(不能为空)entryType
:entry 类型,可选项(默认为 EntryType.OUT
)blockHandler
/ blockHandlerClass
: blockHandler
对应处理 BlockException
的函数名称,可选项。blockHandler 函数访问范围需要是 public
,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException
。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass
为对应的类的 Class
对象,注意对应的函数必需为 static 函数,否则无法解析。fallback
:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore
里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
Throwable
类型的参数用于接收对应的异常。fallbackClass
为对应的类的 Class
对象,注意对应的函数必需为 static 函数,否则无法解析。defaultFallback
(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore
里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
Throwable
类型的参数用于接收对应的异常。fallbackClass
为对应的类的 Class
对象,注意对应的函数必需为 static 函数,否则无法解析。exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。注:1.6.0 之前的版本 fallback 函数只针对降级异常(
DegradeException
)进行处理,不能针对业务异常进行处理。
特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException
时只会进入 blockHandler
处理逻辑。若未配置 blockHandler
、fallback
和 defaultFallback
,则被限流降级时会将 BlockException
直接抛出(若方法本身未定义 throws BlockException 则会被 JVM 包装一层 UndeclaredThrowableException
)。
进行测试:
先执行2,在5秒里面返回都是这个。
加载本地配置
cloud: sentinel: transport: dashboard: 192.168.180.137:8887 #sentinel控制台的请求地址 datasource: ds1: file: file: classpath:flowrule.json data-type: json rule-type: flow eager: true #立即加载
[ { "resource": "orderFindById", "controlBehavior": 0, "count": 1, "grade": 1, "limitApp": "default", "strategy": 0 } ]
Rest实现熔断
Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造
RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。
@LoadBalanced @Bean @SentinelRestTemplate(fallbackClass = ExceptionUtils.class,fallback = "handleFallback", blockHandler = "handleBlock" ,blockHandlerClass = ExceptionUtils.class ) public RestTemplate restTemplate() { return new RestTemplate(); }
@SentinelRestTemplate 注解的属性支持限流( blockHandler , blockHandlerClass )和降级
( fallback , fallbackClass )的处理。
其中 blockHandler 或 fallback 属性对应的方法必须是对应 blockHandlerClass 或
fallbackClass 属性中的静态方法。
该方法的参数跟返回值跟
org.springframework.http.client.ClientHttpRequestInterceptor#interceptor 方法一
致,其中参数多出了一个 BlockException 参数用于获取 Sentinel 捕获的异常。
比如上述 @SentinelRestTemplate 注解中 ExceptionUtil 的 handleException 属性对应的方法
声明如下:
public class ExceptionUtils { /** * 静态方法 * 返回值: SentinelClientHttpResponse * 参数 : request , byte[] , clientRquestExcetion , blockException */ //限流熔断业务逻辑 public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) { Product product = new Product(); product.setProductDesc("限流熔断"); return new SentinelClientHttpResponse(JSON.toJSONString(product)); } //异常降级业务逻辑 public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) { Product product = new Product(); product.setProductDesc("异常降级"); return new SentinelClientHttpResponse(JSON.toJSONString(product)); } }
1秒里面都执行几次,就会这样
Feign实现熔断
Sentinel 适配了 Feign 组件。如果想使用,除了引入 sentinel -starter 的依赖外还需要 2 个步骤:
配置文件打开 sentinel 对 feign 的支持: feign.sentinel.enabled=true
加入 openfeign starter 依赖使 sentinel starter 中的自动化配置类生效:
(1) 引入依赖
<!--springcloud整合的openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
( 2) 开启sentinel 支持
在工程的application.yml中添加sentinel 对 feign 的支持
feign:
sentinel:
enabled: true
( 3)配置FeignClient
和使用Hystrix的方式基本一致,需要配置FeignClient接口以及通过 fallback 指定熔断降级方法
/** * 声明需要调用的微服务名称 * @FeignClient * * name : 服务提供者的名称 * * fallback : 配置熔断发生降级方法 * 实现类 */ @FeignClient(name="service-product",fallback = ProductFeignClientCallBack.class) public interface ProductFeignClient { /** * 配置需要调用的微服务接口 */ @RequestMapping(value="/product/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id); }
@Component public class ProductFeignClientCallBack implements ProductFeignClient { /** * 熔断降级的方法 */ public Product findById(Long id) { Product product = new Product(); product.setProductName("feign调用触发熔断降级方法"); return product; } }
Feign 对应的接口中的资源名策略定义:httpmethod:protocol://requesturl。 @FeignClient 注解中的所有属性,Sentinel 都做了兼容。
ProductFeginClient 接口中方法 findById 对应的资源名为 GET: http://shop-service-product/product/{str}。
标签:mamicode -o 服务提供者 异常类 return 自动 逻辑 并且 ash
原文地址:https://www.cnblogs.com/dalianpai/p/12286966.html