OpenFeign使用

news2024/11/15 23:41:27

OpenFeign使用

在微服务的架构中,传统的http客户端如Httpclient Okhttp HttpURLConnection RestTemplate WebClient 显然不适合。毕竟需要动态的获取服务地址,和进行负载均衡调用。

RPC框架

PC 全称是 Remote Procedure Call ,即远程过程调用,其对应的是我们的本地调用。
RPC 的目的是:让我们调用远程方法像调用本地方法一样。

具体过程就是一个服务端调用本地方法一样调用服务,rpc框架客户端会根据相应的方法的注解生成代理对象,然后代理对象中对方法名称,参数对象信息进行序列化,根据服务名称从注册中心获取需要请求的服务的地址,更据配置的协议请求对应的服务地址,服务端接收到请求之后,会根据服务名称找到对应的接口进行调用,调用完成后将结果进行序列化响应给客户端。

常用的Rpc框架有dubbo,OpenFegin,Grpc等

OpenFegin介绍

官方文档:https://docs.spring.io/spring-cloud-openfeign/docs/3.1.5/reference/html/

Feign是Netflix开发的声明式、模板化的HTTP客户端,是一款早期的rpc框架。

Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。

Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便。

OpenFegin基础示例

1、引入依赖

我使用的springCloud版本是2021

        <!--nacos-服务注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--1. 添加openfeign依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        
         <!-- 客户端负载均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>

2、服务启动类上添加**@EnableFeignClients**

仅仅客户端添加,服务端只要能提供http接口即可

@SpringBootApplication
@Slf4j
// 用于开启Fegin客户端
@EnableFeignClients
public class OpenFeignApplication {


    public static void main(String[] args) {

        SpringApplication.run(OpenFeignApplication.class, args);
        log.info("{} startup success", "OpenfeginApplication");

    }
}

3、客服端和服务端代码示例

客户端代码示例

@RestController
@RequestMapping(value = "/feign")
public class OpenFeignController {

    @Autowired
    private FeignService feignService;


    @RequestMapping("/test")
    public String get() {
        Store stores = feignService.getStores(2L);
        feignService.delete(1L);
        Store update = feignService.update(2L, new Store());
        return "陈宫";
    }

}

@FeignClient("nacos-producer")// 此处对应的是服务名称
public interface FeignService {
    @RequestMapping(method = RequestMethod.GET, value = "/nacos-producer/stores/{storeId}")
    Store getStores(@PathVariable("storeId") Long storeId);

    @RequestMapping(method = RequestMethod.POST, value = "/nacos-producer/stores/{storeId}", consumes = "application/json")
    Store update(@PathVariable("storeId") Long storeId, Store store);

    @RequestMapping(method = RequestMethod.DELETE, value = "/nacos-producer/stores/{storeId}")
    void delete(@PathVariable("storeId") Long storeId);
}

服务端代码示例

@RestController
@RequestMapping("/stores")
@Slf4j
public class StoreController {

    @DeleteMapping("/{storeId}")
    public void delete(@PathVariable Long storeId)  {
      log.info("删除成功");
    }
    @PostMapping("/{storeId}")
    public Store update(@PathVariable("storeId") Long storeId , @RequestBody Store store)  {
        log.info("修改成功");
        return store;
    }

    @GetMapping("/{storeId}")
    public  Store getStores2(@PathVariable Long storeId)  {
        log.info("1");
        Store store = new Store();
        return store;
    }
}

说明

客户端调用是否成功和最终的拼接的请求路径是否和服务端接口的请求路径一致,返回对象不一致也只是客户端请求成功后反序列化失败而已。

配置优先级

@EnableFeignClients可以指定全局的配置类,或者@Configuration注解下被扫描到的Feign的配置都是全局配置

@EnableFeignClients(basePackages = {"cn.sry1201.*","cn.sry"},defaultConfiguration = FeignConfig.class)

局部的注解配置类

@FeignClient(name = "nacos-producer2",configuration = FeignConfig.class)// 可以指定配置类,配置类中进行一些配置

还有全局配置文件和局部的配置文件

默认的优先级是 局部文件配置>全局默认文件配置>局部注解配置>全局默认注解配置

@FeignClient属性

不通过注册中心调用接口

如果引入了注册中心依赖,以我这个版本为例,接口请求路径中的ip和端口都是服务名,最终客户端负载均衡器会从注册中心获取对一个服务名的ip地址,然后替换成实际ip进行访问

我们也可以直接通过ip地址访问,示例如下,将基础示例中的配置改成如下进行测试即可

@FeignClient(name = "nacos-producer2",url = "http://localhost:8004")

动态设置@FeignClient属性

@FeignClient(name = "${feign.name}", url = "${feign.url}")
public interface StoreClient {
    //..
}

配置类

@FeignClient(name = "nacos-producer2",configuration = FeignConfig.class)// 可以指定配置类,配置类中进行一些配置

配置类分全局配置和局部配置,如果加了@Configuration注解那就是全局配置

feign.Logger

日志级别

这里的logger是feign.Logger

public class FeignConfig {

    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

通过源码可以看到日志等级有 4 种,分别是:

  • NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。
  • BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。
  • HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
  • FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。

当然上述级别说的是在springboot打印debug级别日志的情况下,feign定义的日志级别来打印不同完整度的日志,所以需要指定@FeignClient所在类的日志级别为debug,似乎不需要到日志的配置文件中操作,外部指定对应的记录器日志级别同样生效

logging:
  # 指定日志配置文件位置,指定之后,外部配置文件失效,但是可以被配置文件内部引用,注意logback-spring.xml这个名称不能修改
  config: classpath:log/logback-spring.xml
  level:
    #指定根记录器的级别,
    root: debug
    # 单独指定某个记录器的日志级别
    cn.sry1201.producer.service: debug

以下是FULL级别的日志

支持Feign原生的注解

Spring Cloud 在 Feign 的基础上做了扩展,使用 Spring MVC 的注解来完成Feign的功能。原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。

1、配置类中添加配置

    /**
     * 修改契约配置,支持Feign原生的注解
     * @return
    @Bean
    public Contract feignContract() {
        return new Contract.Default();
    }

2、使用feign原生注解示例

@FeignClient(value = "mall-order",path = "/order")
public interface OrderFeignService {
    @RequestLine("GET /findOrderByUserId/{userId}")
    public R findOrderByUserId(@Param("userId") Integer userId);
}

超时时间配置

配置类中添加配置

// 分别是连接超时时间和读取超时时间
@Bean
public Request.Options options() {
return new Request.Options(5000, 10000);
}

自定义请求拦截器

public class FeignAuthRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        // 业务逻辑
        String access_token = UUID.randomUUID().toString();
        template.header("Authorization",access_token);
    }
}

@Configuration  // 全局配置
public class FeignConfig {
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
    /**
     * 自定义拦截器
     * @return
     */
    @Bean
    public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){
        return new FeignAuthRequestInterceptor();
    }
}

配置文件

局部配置类中局部配置在配置文件中的实现

# feign日志局部配置
feign:
  client:
    config:
      nacos-producer:
        loggerLevel: BASIC
#        contract: feign.Contract.Default #设置为默认的契约  (还原成原生注解)
        # 连接超时时间,默认2s
        connectTimeout: 5000
        # 请求处理超时时间,默认5s
        readTimeout: 10000
        request-interceptors:
          - cn.sry1201.producer.intercepter.feign.CustomFeignInterceptor

配置优先级验证

添加配置和配置类的情况下,打印日志如下,显然是配置文件中配置优先级高

客户端组件配置

Feign 中默认使用 JDK 原生的 URLConnection 发送 HTTP 请求,我们可以集成别的组件来替换掉 URLConnection,比如 Apache HttpClient,OkHttp。

feign:
  #feign 使用 okhttp
  httpclient:
    enabled: false
  okhttp:
    enabled: true#### 配置Apache HttpClient

开启配置后引入相关依赖即可,总之我这里报错了,不管,这个就做个记录吧,知道有这个配置

PoolingHttpClientConnectionManager : Closing expired connections

GZIP 压缩配置(不建议,会导致传输过程出现数据错误等…)

仅做记录,未测试

官方文档:https://docs.spring.io/spring-cloud-openfeign/docs/3.1.5/reference/html/#feign-requestresponse-compression

开启压缩可以有效节约网络资源,提升接口性能,我们可以配置 GZIP 来压缩数据:

feign:
  # 配置 GZIP 来压缩数据
  compression:
    request:
      enabled: true
      # 配置压缩的类型
      mime-types: text/xml,application/xml,application/json
      # 最小压缩值
      min-request-size: 2048
    response:
      enabled: true

注意:只有当 Feign 的 Http Client 不是 okhttp3 的时候,压缩才会生效,配置源码在FeignAcceptGzipEncodingAutoConfiguration

核心代码就是 @ConditionalOnMissingBean(type=“okhttp3.OkHttpClient”),表示 Spring BeanFactory 中不包含指定的 bean 时条件匹配,也就是没有启用 okhttp3 时才会进行压缩配置。

注意事项

1、需要注意的是FeignClient的name属性不可重复

关联信息

  • 关联的主题:
  • 上一篇:
  • 下一篇:
  • image: 20221021/1
  • 转载自:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/79272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NTC-Templates解析与采集H3C(Comware Version 7)信息

本文仅供本人参考与学习NTC-Templates模板使用。 设备环境&#xff1a;HCL S6850 S5820V2-54QS-GE&#xff1b;Version 7.1.075, Alpha 7571 模板采用&#xff1a;hp_comware_display_xxxxxxxx.textfsm 在线模板测试&#xff1a;https://textfsm.nornir.tech/ hp_comware_d…

httpbin的使用

在学习过程中我们想知道我们发送处的http格式是什么样子的&#xff0c;是否符合我们的要求&#xff0c;寻找一个这样的工具&#xff0c;满足验证测试需要。 Httpbin服务可以满足查看我发出去的请求到底是什么样子的。你需要查看请求中的那部分信息&#xff0c;就调用什么样的接…

【Qt入门第37篇】 网络(七)TCP(一)

导语 TCP即TransmissionControl Protocol&#xff0c;传输控制协议。与UDP不同&#xff0c;它是面向连接和数据流的可靠传输协议。也就是说&#xff0c;它能使一台计算机上的数据无差错的发往网络上的其他计算机&#xff0c;所以当要传输大量数据时&#xff0c;我们选用TCP协议…

游戏开发45课 性能优化4

2.6 粒子 粒子特效也是性能的一个大杀手&#xff0c;主要体现在&#xff1a; 每帧计算量大。涉及发射器/效果器/曲线插值等&#xff0c;耗费CPU性能。频繁操作内存。粒子在生命周期里&#xff0c;实例持续不断地创建/删除&#xff0c;即便有缓存机制下&#xff0c;依然避免不…

算法day43|1049,494,474

1049. 最后一块石头的重量 II class Solution:def lastStoneWeightII(self, stones: List[int]) -> int:summ sum(stones)target summ//2#dp下标和数组的定义,dp[j]代表的是最大价值dp [0]*15001#递归公式for i in range(len(stones)):for j in range(target,stones[i]-…

Zero-Shot Learning across Heterogeneous Overlapping Domains

极简论文阅读 摘要 a zero-shot learning approach:零样本学习方法。 natural language understanding domain&#xff1a;自然语言处理域。 a given utterance&#xff1a;给定的话语。 domains at runtime&#xff1a;运行时的域。 utterances and domains 给定话语和域。 …

Yolact

YOLACT 1.Abstract 原理: 生成一组 prototype masks (原型掩码) 个数&#xff08;nm&#xff09;可自定义&#xff0c;基于protonet的最后一组卷积核个数 通过一组 coefficients (掩码系数) 预测每个 instance mask (输出mask) 掩码系数由head层输出&#xff0c;shape为&…

微服务框架 SpringCloud微服务架构 微服务保护 32 隔离和降级 32.2 线程隔离

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护32 隔离和降级32.2 线程隔离32.2.1 线程隔离32.2.2 优缺点对比32 隔离和降级 32.2 线程隔离 32.…

算法7:平衡二叉树(AVLTree)

二叉排序树&#xff08;BST, Binary Sort Tree&#xff09;也称二叉查找树&#xff08;Binary Search Tree&#xff09;, 或二叉搜索树。 定义&#xff1a;一颗二叉树&#xff0c;满足以下属性&#xff1a; 左子树的所有的值小于根节点的值右子树的所有值大于根节点的值左、右…

关键词(四)

关键词&#xff08;四&#xff09;一.具有争议的关键词—goto二.“空”的关键字—void1.void为什么不能定义变量2.void修饰函数返回值和参数3.void指针一.具有争议的关键词—goto goto语句非常灵活&#xff0c;其实就是从goto这个位置直接跳转到goto后面的那个数据&#xff08;…

单例模式、工厂模式

单例模式、一、单例模式1.1 饿汉模式1.1.1 实现1.1.2 补充1.2 懒汉模式1.2.1 单线程版1.2.2 多线程版二、工厂模式一、单例模式 单例模式是校招中最常考的设计模式之一。 啥是设计模式&#xff1f; 设计模式好比象棋中的"棋谱"&#xff1a;红方当头炮&#xff0c;黑…

软件测试人员究竟要掌握什么技能?顺便说下行业现状

最近团队内部产品在做性能测试中碰到一个问题&#xff0c;不仅仅这次性能测试&#xff0c;其实这在我这近10年工作过程中&#xff0c;经常碰到一些类似的事情&#xff0c;今天拿出来一件事说叨说叨。 1、事情经过 月中上线了一个功能&#xff0c;该功能会应对峰值流量&#x…

【安卓APP源码和设计报告(含PPT)——订餐系统

订餐系统实验报告 课程名称&#xff1a; Android程序设计 班 级&#xff1a; 学 号&#xff1a; 姓 名&#xff1a; 任课教师&#xff1a; 程序功能与环境&#xff08;服务器&#xff0c;手机实物照片&#xff0c;自己拍&#xff09; 程序功能 餐厅订餐系统服务器&#…

45. python %占位符格式化处理

45. %占位符格式化处理 文章目录45. %占位符格式化处理1.课题导入2. %占位符概念3. %d格式化为整数3.1 %d将整数格式化到指定位置3.2 %d将浮点数格式化为整数1. 知识回顾&#xff1a;用int函数将浮点数转换为整数2. 用%将浮点数格式化为整数4. %s格式化为字符串4.1 %s将整数格式…

论文笔记-时序预测-Triformer

论文标题&#xff1a; Triformer: Triangular, Variable-Specific Attentions for Long Sequence Multivariate Time Series Forecasting 论文链接&#xff1a; https://arxiv.org/abs/2204.13767v1 代码链接&#xff1a; https://github.com/razvanc92/triformer 摘要 各种现…

[附源码]计算机毕业设计基于JEE平台springbt技术的订餐系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Spring源码解析-环境变量

“不积跬步&#xff0c;无以至千里”。 今天聊一聊Spring中环境变量的动态添加和填充Bean属性的时候一些带“$”符号的属性值的解析问题。 因为最近做项目的时候发现了一个有意思的问题&#xff0c;之前也没关注过。因为项目中使用的容器类型是GenericXmlApplicationContext&a…

从GPT-3到CHAT-GPT(CHAT-GPT如何申请)

回顾2020年7月 2020年7月份有一个重大新闻&#xff0c;人工智能科研公司OpenAI&#xff0c;推出了它的新一代语言模型 GPT-3&#xff08;Generative Pretrained Transformer 3&#xff09;&#xff0c;这个事情在社交媒体影响甚广&#xff0c;甚至有一篇文章《一个新型 AI 震惊…

动态代理详解

目录 一、动态代理_代理模式简介 二、动态代理_JDK动态代理 dynamic 三、动态代理_CGLib动态代理 四、JDK和CGLib动态代理的区别 一、动态代理_代理模式简介 代理模式是23种设计模式之一。设计模式是前人总结的&#xff0c;在软件开发过程遇到常用问题的解决方案&#xff0…

微服务框架 SpringCloud微服务架构 微服务保护 30 初识Sentinel 30.4 引入cloud-demo

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护30 初识Sentinel30.4 引入cloud-demo30.4.1 引入cloud-demo30.4.2 微服务整合Sentinel30 初识Sent…