springcloud 组件之 Feign 实战使用(五)

落日映苍穹つ 2022-11-30 04:14 343阅读 0赞

Feign 组件是对 Hystrix 和Ribbon 两个组件的再封装,同时把公用的接口提取出来 简化了代码量,便于统一管理。使用流程如下:

一、使用流程:

1、jar 包引入

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>

2、启动类注解配置 Feign 的功能,核心代码如下:

  1. @SpringBootApplication(scanBasePackages = {"com.nandao.anan"})
  2. //注册到eureka
  3. @EnableEurekaClient
  4. //开启断路器功能
  5. @EnableCircuitBreaker
  6. //开启feign支持,clients指定哪个类开启feign
  7. @EnableFeignClients(clients = {StudentService.class,TeacherServiceFeign.class})
  8. //或者指定某个目录
  9. //@EnableFeignClients(basePackages={"com.info.uas.*","com.info.dts.*"})
  10. public class MicroWebnoApplication {
  11. public static void main(String[] args) {
  12. SpringApplication.run(MicroWebnoApplication.class,args);
  13. }
  14. }

3、Feign 的客户端 核心代码配置如下:

  1. /*
  2. * fallback = StudentServiceFallback.class 可以简单处理异常,不能获取具体异常,相当于Hystrix 的降级方法
  3. * fallbackFactory = StudentServiceFallbackFactory.class 可以具体分析异常,相当于Hystrix 的降级方法,
  4. * Feign 没有默认的降级方法
  5. * */
  6. @FeignClient(name = "MICRO-ORDER-NO",path = "/feign"
  7. /*fallback = StudentServiceFallback.class,*/
  8. ,fallbackFactory = StudentServiceFallbackFactory.class)
  9. public interface StudentService {
  10. @GetMapping("/student/getAllStudent")
  11. String getAllStudent();
  12. @PostMapping("/student/saveStudent")
  13. String saveStudent(@RequestBody Student student);
  14. }

4、Feign 的服务端controller接口核心代码如下:

  1. @Slf4j
  2. @RestController
  3. public class StudentController implements StudentService {
  4. private org.slf4j.Logger log = LoggerFactory.getLogger(getClass());
  5. @Autowired
  6. private StudentService studentService;
  7. @RequestMapping("/feign/student/getAllStudent")
  8. @Override
  9. public String getAllStudent() {
  10. return studentService.getAllStudent();
  11. }
  12. @RequestMapping("/feign/student/saveStudent")
  13. @Override
  14. public String saveStudent(@RequestBody Student student) {
  15. return studentService.saveStudent(student);
  16. }

5、主要几点:服务端接口必须定义跟 feign 客户端相同的 url;传递和接收的参数类型必须一致。

二、抽取公共方法:

把feign 的接口抽取成公共的api ,作为一个单独的微服务,打成jar ,通过maven 私服,依赖到各微服务中,流程如下:

1、创建单独的公共api 微服务,如图:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25hbmRhbzE1OA_size_16_color_FFFFFF_t_70

2、其他多个微服务去引用,比如:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25hbmRhbzE1OA_size_16_color_FFFFFF_t_70 1

3、这样就可以相互调用了,此方案耦合性比较强。

三、Feign 的降级,如图:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25hbmRhbzE1OA_size_16_color_FFFFFF_t_70 2

1、两种降级方法核心代码如下图:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25hbmRhbzE1OA_size_16_color_FFFFFF_t_70 3

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25hbmRhbzE1OA_size_16_color_FFFFFF_t_70 4

  1. final String msg = throwable.getMessage();//这是过滤器得到的结果,再走核心降级方法。

2、此降级方法就是封装的Hystrix 的功能的实现。

四、Feign 的全局过滤器功能,如果接口出现问题,先走过滤器方法,再走降级方法,简单demo如下:

  1. import feign.Response;
  2. import feign.Util;
  3. import feign.codec.ErrorDecoder;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import java.io.IOException;
  9. @Configuration
  10. public class FeignErrMessageFilter {
  11. @Bean
  12. public ErrorDecoder errorDecoder() {
  13. return new FeignErrorDecoder();
  14. }
  15. /*
  16. * 当调用服务时,如果服务返回的状态码不是200,就会进入到Feign的ErrorDecoder中
  17. * {"timestamp":"2020-02-17T14:01:18.080+0000","status":500,"error":"Internal Server Error","message":"/ by zero","path":"/feign/student/errorMessage"}
  18. * 只有这种方式才能获取所有的被feign包装过的异常信息
  19. * 这里如果创建的Exception是HystrixBadRequestException
  20. * 则不会走熔断逻辑,不记入熔断统计
  21. * */
  22. class FeignErrorDecoder implements ErrorDecoder {
  23. private Logger logger = LoggerFactory.getLogger(FeignErrorDecoder.class);
  24. @Override
  25. public Exception decode(String s, Response response) {
  26. RuntimeException runtimeException = null;
  27. try {
  28. String retMsg = Util.toString(response.body().asReader());
  29. logger.info(retMsg);
  30. runtimeException = new RuntimeException(retMsg);
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. }
  34. return runtimeException;
  35. }
  36. }
  37. }

这个过滤器是对异常信息的再封装,把 feign 的异常信息封装成我们系统的通用异常对象 ,过滤器把异常返回后,feign 前面定义的降级方法就会调到 create 方法,Feign 我不建议大家使用,流程简单并发不高的方法可以用一用。

Feign 的使用已经介绍完,过程中我们发现 该组件增加了代码的耦合性,使得接口的响应速度变慢(因为封装了Hystrix 和Ribbon功能),所以Feign组件不适合业务场景复杂的接口。下一期我们分析 分布式配置中心,敬请期待!

发表评论

表情:
评论列表 (有 0 条评论,343人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SpringCloud-feign

    方面微服务之间的调用、访问 因为restTemplate使用虽然简单,但是在访问方需要指定被调用方的微服务名、url,这样在开发过程中、后期要进行为期其实非常麻烦。 Sp

    相关 SpringCloudFeign()

    Feign简介   Feign 是一个声明web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Fe