http客户端Feign使用

news2024/11/23 19:20:10

一、RestTemplate方式调用存在的问题

先来看我们以前利用RestTemplate发起远程调用的代码:

String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);

存在下面的问题:

  • 代码可读性差,编程体验不统一
  • 参数复杂,URL难以维护

二、Feign的介绍

Feign是Spring Cloud提供的声明式的HTTP客户端, 它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

Spring Cloud集成Feign并对其进行了增强,使Feign支持了Spring MVC注解;Feign默认集成了Ribbon,所以Fegin默认就实现了负载均衡的效果。

三、定义和使用Feign客户端

Feign的使用步骤:

  • 引入依赖
  • 添加@EnableFeignClients注解
  • 编写FeignClient接口(客户端)
  • 使用FeignClient中定义的方法代替RestTemplate

具体使用Feign的步骤如下,以order-service为例:
1、在order-service服务中引入依赖:

        <!-- feign客户端依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2、在order-service服务的启动类添加注解开启Feign的功能:

@EnableFeignClients
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

3、编写Feign客户端:

@FeignClient("userservice")
public interface UserClient {
    @GetMapping("/user/{id}")
    User getById(@PathVariable("id") Long id);
}

主要是基于SpringMVC的注解来声明远程调用的信息,比如:

  • 服务名称:userservice
  • 请求方式:GET
  • 请求路径:/user/{id}
  • 请求参数:Long id
  • 返回值类型:User

4、用Feign客户端代替RestTemplate:

    @Autowired
    private UserClient userClient;
    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.利用feign 发送http请求,查询用户
        User user = userClient.getById(order.getUserId());
        // 3.封装到order里面
        order.setUser(user);
        // 4.返回
        return order;
    }

四、自定义Feign的配置

Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:
在这里插入图片描述
一般我们需要配置的就是日志级别。

配置Feign日志有两种方式:

方式一:配置文件方式 (相比之下更简单)

  • 全局生效:
feign:
  client:
    config:
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        logger-level: FULL #  日志级别
  • 局部生效:
feign:
  client:
    config:
      userservice: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        logger-level: FULL #  日志级别

方式二:java代码方式,需要先声明一个Bean

public class FeignClientConfig {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC;
    }
}
  • 如果是全局配置,则把它放到@EnableFeignClients这个注解中:
@EnableFeignClients(defaultConfiguration = FeignClientConfig.class)
  • 如果是局部配置,则把它放到@FeignClient这个注解中:
@FeignClient(value = "userservice", configuration = FeignClientConfig.class) 

五、Feign的性能优化

Feign底层的客户端实现:

  • URLConnection:默认是这种实现,不支持连接池,jdk自带,性能不太好,没有连接池,建立连接和销毁的损耗比较大(三次握手,四次挥手)。
  • Apache HttpClient :支持连接池
  • OKHttp:支持连接池

因此优化Feign的性能主要包括:

  1. 使用连接池代替默认的URLConnection
  2. 日志级别,最好用basic或none

因此对Feign添加HttpClient的支持,日志级别尽量用basic,步骤如下:
1、引入httpclient依赖:

        <!--httpClient的依赖 -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>

2、配置连接池:

feign:
  client:
    config:
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        logger-level: BASIC #  日志级别
  httpclient:
    enabled: true # 开启feign对HttpClient的支持
    max-connections: 200 # 最大的连接数
    max-connections-per-route: 50 #单个路径最大的连接数

六、Feign的最佳实践

  1. 方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。

在这里插入图片描述
缺点:

  • 服务紧耦合
  • 父接口参数列表中的映射不会被继承(springmvc)
  1. 方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,打成一个jar包,提供给所有消费者,只需要引入依赖就可以使用。
    在这里插入图片描述

缺点:

  • 模块中的方法对于其他服务可能多余了,用不到。

实现最佳实践方式二的步骤如下:

  1. 首先创建一个module,命名为feign-api,然后引入feign的starter依赖
  2. 将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
  3. 在order-service中引入feign-api的依赖
  4. 修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包重启测试

这里会出现一个问题,当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。
有两种方式解决:

  • 方式一:在@EnableFeignClients注解中添加basePackages,指定FeignClient所在的包。
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
  • 方式二:在@EnableFeignClients注解中添加clients,指定具体FeignClient的字节码。
@EnableFeignClients(clients = {UserClient.class})

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

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

相关文章

Mosh Java课程自学(一)

目录 一、前言 二、全局介绍 三、Types 一、前言 首先推荐一下B站上转载的Mosh讲Java课程&#xff0c;当然&#xff0c;建议有一定基础并且英文水平尚可的同学学习&#xff0c;否则你可能会被搞得很累并逐渐失去对编程的兴趣。 Mosh 【JAVA终极教程】中英文字幕 高清完整版…

口袋参谋:如何高效一键下载真实买家秀?

​在淘宝天猫上&#xff0c;即使卖一支笔都有上万个宝贝竞争&#xff0c;所有卖家拼的就是权重带来的曝光度&#xff0c;能展示给买家多少&#xff0c;自己收获多少流量。 如何用自己的优势将流量访客转化为顾客&#xff0c;提升店铺的转化率。而买家秀&#xff0c;就是为此而生…

Java常用类之 String、StringBuffer、StringBuilder

Java常用类 文章目录 一、字符串相关的类1.1、String的 不可变性1.2、String不同实例化方式的对比1.3、String不同拼接操作的对比1.4、String的常用方法1.5、String类与其他结构之间的转换1.5.1、String 与基本数据类型、包装类之间的转换1.5.2、String 与char[]的转换1.5.3、…

ipad可以使用其他品牌的手写笔吗?开学平价电容笔推荐

新学期已经来临&#xff0c;相信不少同学已经开始着手筹备新学期的该准备什么了&#xff0c;毕竟原装的苹果Pencil&#xff0c;功能强大&#xff0c;但价格昂贵&#xff0c;一般人根本买不起。那么&#xff0c;有没有像苹果原装那样的电容笔呢&#xff1f;当然是有的。国产的平…

长安链上线可视化敏捷测试工具v1.0版本

开发者对区块链底层平台进行初步的了解后&#xff0c;一项经常会涉及到的工作是对平台进行测试以考量其性能及稳定性是否符合自身使用需求。长安链推出了可视化UI操作界面的区块链敏捷测试工具v1.0版本&#xff0c;当前版本可对内置合约进行压测并生成网络拓扑图以验证组网方式…

免费开箱即用微鳄售后工单管理系统

编者按&#xff1a;本文介绍基于天翎MyApps低代码平台开发的微鳄售后工单管理系统&#xff0c; 引入低代码平台可以帮助企业快速搭建和部署售后工单管理系统&#xff0c; 以工作流作为支撑&#xff0c;在线完成各环节数据审批&#xff0c;解决售后 工单 服务的全生命周期过程管…

《2023中国氢能源行业分析报告》丨附下载_三叠云

✦ ✦✦ ✦✦ ✦✦ ✦ 1. 国内氢能政策梳理 直接涉及氢能政策&#xff1a;1&#xff09;21年以来&#xff0c;发布国家级10个、省级83个、 市县级252个&#xff1b;2&#xff09;涉及发展规划占比45%、财政支持占比 20%、项目支持占比17%、管理办法占比16%、 氢能安全和标准占…

公私钥非对称加密 生成和验证JSON Web Token (JWT)

前言 这是我在这个网站整理的笔记&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 公私钥非对称加密 生成和验证JSON Web Token 什么是JSON Web Token (JWT)Java程序中生成和验证JWT代码解析 什么是JSON Web Token (JWT) JSON Web Tok…

【C++】泛型算法(二)泛型指针Iterator(迭代器)

迭代器iterator定义 迭代器是一种检查容器内元素并遍历元素的数据类型&#xff1b;迭代器提供一个对容器对象或者string对象的访问方法&#xff0c;并定义了容器范围&#xff1b;迭代器的使用可以提高编程的效率。 其定义应该提供&#xff1a; 迭代对象&#xff08;某个容器&a…

拆贡献算总和(抓住双射)+竞赛图与连通分量相关计数:arc163_d

https://atcoder.jp/contests/arc163/tasks/arc163_d 首先竞赛图有个性质&#xff1a; 然后有了这个性质&#xff0c;我们就可以考虑计数题的经典套路&#xff0c;拆贡献算总和。 考虑假如我们成功划分成两个集合 A , B A,B A,B&#xff0c;其中一个可以为空&#xff08;我们…

Qt --- Day02

实现效果&#xff1a; 点击登录&#xff0c;检验用户密码是否正确&#xff0c;正确则弹出消息框&#xff0c;点击ok转到另一个页面 不正确跳出错误消息框&#xff0c;默认选线为Cancel&#xff0c;点击Yes继续登录 点击Cancel跳出问题消息框&#xff0c;默认选项No&#xff0c…

netty之pipeline

Netty抽象出流水线(pipeline)这一层数据结构进行处理或拦截channel相关事件。 事件分为入站事件(inBound event)和出站事件(outBound event)的ChannelHandlers列表。ChannelPipeline使用先进的Intercepting Filter模式&#xff0c;使用户可以完全控制如何处理事件以及管道中的…

全流程GMS地下水数值模拟及溶质(包含反应性溶质)运移模拟技术教程

详情点击公众号链接&#xff1a;全流程GMS地下水数值模拟及溶质&#xff08;包含反应性溶质&#xff09;运移模拟技术教程 前言 GMS三维地质结构建模 GMS地下水流数值模拟 GMS溶质运移数值模拟与反应性溶质运移模 详情 1.GMS的建模数据的收集、数据预处理以及格式等&#xff…

2023/9/18 -- C++/QT

作业 完善登录框 点击登录按钮后&#xff0c;判断账号&#xff08;admin&#xff09;和密码&#xff08;123456&#xff09;是否一致&#xff0c;如果匹配失败&#xff0c;则弹出错误对话框&#xff0c;文本内容“账号密码不匹配&#xff0c;是否重新登录”&#xff0c;给定两…

《Linux运维总结:Centos7.6之OpenSSH7.4升级版本至9.4》

一、环境信息 操作系统&#xff1a;Centos7.6.1810 OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 如下图所示&#xff1a; 注意&#xff1a;升级后由于加密算法的区别&#xff0c;低版本的SSH工具可能无法连接&#xff0c;建议改用Xshell7或SecureCRT9.0以上版本。 二、注意事项 1、检…

第九章 关系查询处理和查询优化

第九章 关系查询处理和查询优化 9.1 关系数据库系统的查询处理 9.1.1 查询处理步骤 查询分析 对查询语句进行扫描、词法分析和语法分析&#xff0c; 词法分析&#xff1a;从查询语句中识别出正确的语言符号。语法分析&#xff1a;进行语法检查。 查询检查 合法性检查视图转换…

【java】【SpringBoot】【二】运维实用篇 SpringBoot工程

目录 一、打包与运行 1、程序打包与运行&#xff08;Window版&#xff09; 1.1 打包 1.2 运行 1.3 打包插件 1.4 总结 1.6 命令行启动常见问题及解决方案 2、程序运行&#xff08;Linux版&#xff09; 二、配置高级 1、临时属性设置 2、配置文件分类 3、自定义配置…

Spring Boot + Vue3前后端分离实战wiki知识库系统十三--单点登录开发二

接着https://www.cnblogs.com/webor2006/p/17608839.html继续往下。 登录功能开发&#xff1a; 接下来则来开发用户的登录功能&#xff0c;先准备后端的接口。 后端增加登录接口&#xff1a; 1、UserLoginReq&#xff1a; 先来准备用户登录的请求实体&#xff1a; package com…

07JVM_内存模型和CAS与原子类

一、内存模型 1.java内存模型 Java内存结构是JMM&#xff08;Java Memory Model&#xff09;的意思。JMM定义了一套在多线程读写共享数据&#xff08;成员变量&#xff0c;数组&#xff09;时&#xff0c;对数据的原子性&#xff0c;见性&#xff0c;有序性的规则和保障。 1…