SpringCloud中Feign与Sentinel整合实现隔离和熔断降级。

2022-12-01 08:35:43

前言

最近在学习springcloudAlibaba的过程中,遇到了不少的问题,刚好有时间,想把自己遇到的问题在此做一个记录,也希望能够让读者从中得到一点提示,避免采坑。本次就SpringCloud中Feign与Sentinel整合实现隔离和熔断降级时遇到的问题做一个记录。


一、隔离和降级?

限流是一种预防措施,虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。

而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了。

线程隔离:调用者在调用服务提供者时,给每个调用的请求分配独立线程池,出现故障时,最多消耗这个线程池内资源,避免把调用者的所有资源耗尽。
熔断降级:是在调用方这边加入断路器,统计对服务提供者的调用,如果调用的失败比例过高,则熔断该业务,不允许访问该服务的提供者了。

可以看到,不管是线程隔离还是熔断降级,都是对客户端(调用方)的保护。需要在调用方 发起远程调用时做线程隔离、或者服务熔断。

而我们的微服务远程调用都是基于Feign来完成的,因此我们需要将Feign与Sentinel整合,在Feign里面实现线程隔离和服务熔断。

二、整合步骤

1.修改配置,开启sentinel功能

代码如下:
修改消费者服务的application.yml文件,开启Feign的Sentinel功能:

feign:
  sentinel:
    enabled: true # 开启feign对sentinel的支持

2.编写失败降级逻辑

业务失败后,不能直接报错,而应该返回用户一个友好提示或者默认结果,这个就是失败降级逻辑。

给FeignClient编写失败后的降级逻辑

①方式一:FallbackClass,无法对远程调用的异常做处理

②方式二:FallbackFactory,可以对远程调用的异常做处理,我们选择这种

步骤一:在feing-api项目中定义类,实现FallbackFactory:
在这里插入图片描述

代码示例:

@Slf4j//@ComponentpublicclassOrderClientFallbackFactoryimplementsFallbackFactory<OrderClient>{@OverridepublicOrderClientcreate(Throwable throwable){returnnewOrderClient(){@OverridepublicOrdergetOrderMessage(int ID){
                log.error("查询订单异常", throwable);returnnewOrder();}};}}

这里需要注意的点,由于对Feign-API做了一个抽取,此类实现了FallbackFactory接口,重写了create方法。

步骤二:在feing-api项目中的DefaultFeignConfiguration类中将OrderClientFallbackFactory注册为一个Bean:
在这里插入图片描述
代码示例:

@ConfigurationpublicclassDefaultFeignConfiguration{@BeanpublicLogger.LevellogLevel(){returnLogger.Level.BASIC;}@BeanpublicOrderClientFallbackFactoryorderClientFallbackFactory(){returnnewOrderClientFallbackFactory();}}

这里是通过配置类的方式,将编写的降级逻辑类注入到容器中,注意两个注解:@Configuration、 @Bean。也可以在降级逻辑类上加上@Component注解,两者效果相同,取其中一种即可。

步骤三:在feing-api项目中的OrderClient接口中使用OrderClientFallbackFactory:

@FeignClient(value="orderservice", fallbackFactory=OrderClientFallbackFactory.class)publicinterfaceOrderClient{@GetMapping("/order/orderMessage")OrdergetOrderMessage(@RequestParam("ID")int ID);

注意@FeignClient(value = “orderservice”, fallbackFactory = OrderClientFallbackFactory.class)中的属性使用,使用的是 fallbackFactory。

步骤四:解决以下异常:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'XXX': Unsatisfied dependency expressed through field 'XXXt'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.qst.feign.clients.XXX': Unexpected exception during bean creation; nested exception is java.lang.IllegalStateException: No fallbackFactory instance of type class com.qst.feign.clients.fallback.OrderClientFallbackFactory found for feign client orderservice

java.lang.IllegalStateException: No fallbackFactory instance of type class com.qst.feign.clients.fallback.OrderClientFallbackFactory found for feign client orderservice 是因为Feign接口及其托底函数,需要和启动类平级或为其子包的类,由于feign-api为单独抽取出来的一个模块,因此需要声明扫描对应的接口的包。

消费者服务的启动类代码示例:

@SpringBootApplication@ComponentScan(basePackages={"com.qst.feign","com.qst.ticket"})@EnableFeignClients(clients={OrderClient.class})//开启Feign客户端publicclassTicketDemoApplication{publicstaticvoidmain(String[] args){SpringApplication.run(TicketDemoApplication.class, args);}}

因为@ComponentScan 和@SpringBootApplication注解的包扫描有冲突,@ComponentScan注解包扫描会覆盖掉@SpringBootApplication的包扫描。所以我的例子上需要改成@ComponentScan(basePackages ={“com.qst.feign”,“com.qst.ticket”}) 一个为feign-api的包,另一个为此启动类下的包。

当初出现的问题是只加了对feign-api包的扫描,没有加对此启动类下的包的扫描,导致服务一只出现404的问题,是因为没弄清楚@SpringBootApplication
@ComponentScan,两者的底层原理,学习之路任重而道远啊~

3.重启后,访问一次订单查询业务,然后查看sentinel控制台,可以看到新的簇点链路,然后就可以在sentinel控制台中为所欲为了。


总结

以上就是今天要记录的内容,希望对大家有所帮助。

  • 作者:木 易
  • 原文链接:https://blog.csdn.net/qq_43451671/article/details/121399946
    更新时间:2022-12-01 08:35:43