首页 > 其他分享 >SpringCloud 使用 OpenFeign

SpringCloud 使用 OpenFeign

时间:2024-12-17 23:53:42浏览次数:8  
标签:Spring 服务 service OpenFeign SpringCloud 配置 使用 public stock

一、为什么使用 OpenFeign

在 Spring Cloud 中,使用 OpenFeign主要是为了简化微服务之间的通信,特别是在服务调用的过程中。OpenFeign 是一个声明式的 Web 服务客户端,它能够通过简单的注解方式,快速构建 RESTful 风格的 HTTP 请求。具体来说,使用 OpenFeign 的原因包括以下几个方面:

  1. 简化 HTTP 请求的编写
    OpenFeign 通过注解来声明服务接口,使得微服务之间的通信变得更加简单和直观。开发者只需要定义接口并通过注解描述 HTTP 请求的方式,无需手动编写底层的 HTTP 客户端代码。这样可以减少大量冗余代码,提升开发效率。

示例代码:


// name 服务名称  path 服务路径  configuration 配置类 (可以设置对应的日志级别,需在 yml 中 指定系统级别低于feign的日志级别)
//    服务 路径名 都需要按照调用 Controller 接口的路径来写
//@FeignClient(name = "stock-service", path = "/stock", configuration = OrderConfig.class)
@FeignClient(name = "stock-service", path = "/stock")
public interface StockFeignService {

上述代码中,@FeignClient 注解会告诉 Spring Cloud 自动为 StockClient 接口生成一个代理类,并处理与 stock-service 服务之间的 HTTP 请求。

  1. 集成负载均衡
    Feign 在 Spring Cloud 中默认与 Ribbon 或 Spring Cloud LoadBalancer 集成,能够自动为服务提供负载均衡支持。无需额外的配置,通过 @FeignClient 注解,Feign 会自动从注册中心(如 Nacos、Eureka 等)获取服务实例列表,并进行负载均衡。

  2. 集成熔断器(Hystrix)
    OpenFeign 可以与 Hystrix 或 Resilience4j 等熔断器库集成,从而提供服务调用的容错处理能力。通过声明式注解,开发者可以为 Feign 客户端方法配置熔断规则,避免服务调用失败导致的级联故障。

@FeignClient(name = "stock-service", fallback = StockFallback.class)
public interface StockClient {
    @GetMapping("/stock/test")
    String getStockInfo();
}

@Component
public class StockFallback implements StockClient {
    @Override
    public String getStockInfo() {
        return "Stock service is unavailable";
    }
}

通过上述配置,当 stock-service 服务不可用时,StockFallback 类会返回备用响应,避免整个系统因某个服务故障而崩溃。

  1. 自动处理序列化与反序列化
    Feign 支持自动处理请求和响应的序列化与反序列化。默认情况下,Feign 使用 Jackson 或 Gson 序列化和反序列化请求和响应体。开发者无需手动处理 HTTP 请求的 JSON 序列化工作。
@FeignClient(name = "stock-service")
public interface StockClient {
    @PostMapping("/stock/update")
    void updateStock(@RequestBody Stock stock);
}

这里 Stock 类会自动通过 Feign 转换成 JSON 格式的请求体发送出去。

  1. 支持 Spring AOP(面向切面编程)
    Feign 可以与 Spring AOP 结合,支持在服务调用前后进行额外的处理。比如,可以利用 Spring AOP 来记录请求日志、添加请求头、进行安全认证等。

通过 @FeignClient,你可以很容易地与其他 Spring 组件集成,加入日志、监控、身份认证等功能。

  1. 提高代码可维护性
    使用 Feign 可以减少服务间调用的样板代码,使得代码更加清晰和简洁。在大型微服务系统中,管理多个 HTTP 客户端非常麻烦,而 Feign 可以统一管理所有服务的 HTTP 请求,减少代码重复和维护成本。

  2. 与 Spring Cloud 其他组件无缝集成
    Feign 是 Spring Cloud 生态中的一部分,它能够与 Eureka、Config、Hystrix、Ribbon 等组件无缝集成。借助 Spring Cloud 的其他功能,Feign 可以自动配置、自动发现服务,并处理服务间的请求路由、负载均衡、容错等问题。

  3. 支持异步调用
    Feign 还支持异步调用(在使用 @Async 或 @EnableAsync 注解时),通过结合 Spring 的异步机制,能够提高请求的并发能力和系统的响应性。

使用 OpenFeign 的好处主要体现在以下几个方面:

  • 简化微服务间的 HTTP 调用,减少重复代码;
  • 集成负载均衡 和 容错处理,提高系统可靠性;
  • 自动处理序列化 和 反序列化,减少手动配置的工作量;
  • 与 Spring Cloud 生态无缝集成,支持与其他 Spring Cloud 组件共同工作;
  • 提供 异步调用 和 AOP 支持,增强灵活性。
    在 Spring Cloud 微服务架构中,OpenFeign 是一种非常高效、简洁的服务间通信方式,特别适合用于 RESTful 风格的 API 调用。

二、如何使用OpenFeign

1、引入依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2、添加接口

// name 服务名称  path 服务路径  configuration 配置类 (可以设置对应的日志级别,需在 yml 中 指定系统级别低于feign的日志级别)
//    服务 路径名 都需要按照调用 Controller 接口的路径来写
//@FeignClient(name = "stock-service", path = "/stock", configuration = OrderConfig.class)
@FeignClient(name = "stock-service", path = "/stock")
public interface StockFeignService {

    @GetMapping("/test")
    String testStock();
}

其中:我 stock-service 服务下的 服务实现是这样的:
image

进行对比,可以发现,接口的实现,和我们Controller 层非常相似 我们使用注解实现只需确认:
  • xxxxx-service 要使用的服务
  • 服务的path 路径和对应的请求
  • 参数及请求方式,保持完整一致即可

3、查看调用日志配置

(1)通过注解配置实现

// 使用注解配置:接口添加注解
@FeignClient(name = "stock-service", path = "/stock", configuration = OrderConfig.class)

// 配置文件中
    // 此处配置为全局日志:所有的 feign 都会用到,单独设置可在 feign 接口,或 yml 配置文件设置
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }

(2)通过yml文件配置

spring:
  application:
    name: order
  cloud:
    # feign 的局部日志级别
    openfeign:
      client:
        config:
          stock-service:
            loggerLevel: basic

# SpringBoot 的默认日志级别为 info ,feign的 debug 日志级别就不会输入,所以指定对应的文件夹 日志
logging:
  level:
    com.zjl.order.feign: debug

配置的等级有如下四种:
image
image

4、超时时间配置

(1)、通过配置项全局配置;

//    超时时间配置
    @Bean
    public Request.Options options() {
        return new Request.Options(600, TimeUnit.SECONDS,600,TimeUnit.SECONDS,true);
    }

(2)通过yml文件配置

spring:
  application:
    name: order
  cloud:
    # feign 的局部日志级别
    openfeign:
      client:
        config:
          default: # 默认配置,若服务无特殊指定,则使用默认配置
            loggerLevel: basic
            connect-timeout: 1000
            read-timeout: 1000
          stock-service: # 服务有特殊指定,则使用指定参数
            connect-timeout: 5000
            read-timeout: 5000

5、自定义拦截器设置(request/response)

通过实现接口:RequestInterceptor 实现自定义请求拦截器 通过实现其:public void apply(RequestTemplate template) {} 方法,实现自定义逻辑

通过实现接口:ResponseInterceptor 实现自定义结果拦截器 通过实现其:public Object aroundDecode(InvocationContext invocationContext) {} 方法,实现自定义逻辑 该拦截器系统配置中,单个服务只允许一个,响应流只允许读取一次,如果多次读取,可能需要重新设置相应流

@Slf4j
//@Component
public class FeignRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        template.header("feign-request", "feign-request");
        log.info("FeignRequestInterceptor:【{}】", template.path());
    }
}

@Slf4j
//@Component
public class FeignResponseInterceptor implements ResponseInterceptor {
    @Override
    public Object aroundDecode(InvocationContext invocationContext) {
        log.info("FeignResponseInterceptor:【{}】", invocationContext.response());
        return invocationContext.proceed();
    }
}

// 在配置类中进行配置
    // feign 的全局拦截器 (在发送请求前,进行拦截)
    @Bean
    public RequestInterceptor requestInterceptor()
    {
        return new FeignRequestInterceptor();
    }
// feign 的全局拦截器 (在收到返回结果后,进行拦截)
    @Bean
    public ResponseInterceptor responseInterceptor()
    {
        return new FeignResponseInterceptor();
    }
全局实现方式存在两种
  • 使用配置类注解 如:@Component
  • 使用@Bean在配置类中设置
针对注册服务实现拦截器
spring:
  cloud:
    openfeign:
      client:
        config:
          default: # 默认配置,若服务无特殊指定,则使用默认配置
            loggerLevel: basic
            connect-timeout: 10000
            read-timeout: 10000
          stock-service: # 服务有特殊指定,则使用指定参数
            connect-timeout: 5000
            read-timeout: 5000
            request-interceptors:
              - com.zjl.order.interceptor.FeignRequestInterceptor
            #request-interceptors[0]: com.zjl.order.interceptor.FeignRequestInterceptor
            response-interceptor: com.zjl.order.interceptor.FeignResponseInterceptor
其中:
  • equest-interceptors:是一个列表(注意:列表有两种配置形式)
  • response-interceptor:是单个类(响应流只允许消费一次)

标签:Spring,服务,service,OpenFeign,SpringCloud,配置,使用,public,stock
From: https://www.cnblogs.com/herebug/p/18611329

相关文章

  • 变量a使用了一段内存,变量b也和a使用了相同的内存,如果b把这段内存释放了,a将变为悬空指
    在C++中,如果两个变量(a 和 b)指向同一段内存,并且其中一个变量(如 b)释放了这段内存,那么这段内存就被标记为可供系统重用的空闲内存。此时另一个变量(a)依然保留原有的指针,但它指向的内存已经被释放,成为 悬空指针(danglingpointer)。关键问题内存释放后的行为如果 b 调用了......
  • Windows ANSI API 是指 Windows 操作系统 提供的一组 应用程序编程接口 (API),它们使用
    WindowsANSIAPI是指Windows操作系统提供的一组应用程序编程接口(API),它们使用ANSI字符集来处理字符串和文本数据。ANSI字符集是较为老旧的字符编码标准,通常对应的是Windows-1252编码(又称Latin-1)。这些API主要用于与字符串和字符数据交互。1. WindowsANSI......
  • 使用pjsip封装自定义软电话sdk
    环境:window10_x64&vs2022pjsip版本:2.14.1python版本:3.9.13近期有关于windows环境下软电话sdk开发的需求,需要开发动态库给上层应用调用,今天整理下使用pjsip封装简单的自定义软电话sdk笔记,并提供相关资源下载。我将从以下几个方面展开:功能说明接口设计接口实现接口调用......
  • 关于C语言中指针的使用的练习
    #include<stdio.h>#include<stdlib.h>intmain(){char*arr=NULL;intsize,new_size;//动态分配初始内存printf("Entertheinitialsizeofthearray:");scanf("%d",&size);arr=(char*)malloc(s......
  • C语言关于return在循环语句中的使用(求一个数是否为素数的过程中的思考)
    intjk(inta)//定义一个jk函数判断a是否是素数,是返回1,不是则返回0.{ inti;if(a<2){return0;} elseif(a==2) { return1; } else { for(i=2;i<=a-1;i++) { if(a%i==0) { return0; } } return1; } }intmain(......
  • 2024 Webstorm安装使用教程(附激活,以及常见问题处理)
    第一步:下载Webstorm安装包访问Webstorm官网,下载Webstorm第二步:安装Webstorm下载完成后,进行安装,next,安装完成点击xx关掉程序!第三步:下载补丁Webstorm补丁文件点击获取补丁下载成功后,打开标注的文件文件夹,进入到文件夹/jetbra注意:这个文件夹单独copy一份......
  • 代理 mitmproxy Python启动时,配置 block_global 参数,使用笔记(三)
    代理mitmproxyPython启动时,配置block_global参数,使用笔记(三)为什么要加block_global=false?,若不加,则只能本地拦截,而移动设备,或非本机请求时则无法被拦截将报错如下:Clientconnectionfrom192.167.6.166killedbyblock_globaloption注意:使用Python的非命令行启动,之前的......
  • react hook使用mobx,并使用Provide实现全局注入store
    在React应用中,你可以使用MobX的Provider组件来全局注入你的store,这样你的整个应用都可以访问到这些store。以下是如何使用MobX和ReactHooks配置全局注入的示例:首先,确保你已经安装了MobX和它的React绑定库:npminstallmobxmobx-react-lite然后,创建一个简单的......
  • 2024年最值得使用的18个Python库
    如果说Python是一把锋利的瑞士军刀,那么Python库就是它的多功能模块,让编程变得更加高效和简单。在2024年,Python生态依然蓬勃发展,各类新兴与经典库层出不穷,究竟有哪些库值得我们投入时间学习和使用?这一份清单将成为你提升生产力的利器!2024年,哪些Python库在实际开发中最具价值?无......
  • 使用Swing组件
    译自https://docs.oracle.com/javase/tutorial/uiswing/components/index.html课程介绍UsingTop-LevelContainers本章讲解了如何使用JFrame、JDialog和JApplet类共享的功能——内容窗格、菜单栏和根窗格。还讨论了容器层次结构,即顶层容器所包含的组件树。TheJComponent......