声明式HTTP客户端-Feign 使用入门详解
什么是 OpenFeign
OpenFeign (以下统一简称为 Feign) 是 Netflix 开源的声明式 HTTP 客户端,集成了 Ribbon 的负载均衡、轮询算法和 RestTemplate 的 HTTP 调用等特性,并对其进行封装,使用者只需要在此基础上,定义一个接口,并在接口上标注一个 FeignClient
,便可以实现 HTTP 远程调用,上面的声明式 HTTP 如何理解,可以理解为
只需要声明一个接口,Feign 就会通过你定义的接口,自动给你构造请求的目标地址并请求。
下面介绍下如何在项目中集成 Feign 组件,只需要遵循 SpringBoot 开发三板斧(1、加依赖,2、加注解,3、加配置)即可
环境准备
加依赖
openfeign
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
加注解
@EnableFeignClients
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
加配置(由于 feign 不需要额外在 application.yml 或者 application.properties)中配置,只需要配置好调用微服务的名称和端口即可,下面举个例子,user-center 就是我们调用的微服务
server:
port: 8081
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
# 微服务名称
application:
name: user
新建 OpenFeign 接口
@FeignClient(name = "user")
public interface UserFeignClient {
@GetMapping("/users/{id}")
UserDto findById(@PathVariable Integer id);
}
新建 Controller 层
@Service
public class ArticleController {
@Resource
private UserFeignClient userFeignClient;
public ArticleDto findByUserId(Integer userId) {
... ...
ArticleDto articleDto = this.userFeignClient.findById(userId);
... ...
return articleDto;
}
}
以上,就是 openFeign 的基本使用入门了
Feign的日志配置
由于 Feign 在没有配置的情况下是不会打印任何日志,如果想要看到 Feign 的日志,需要额外的配置;但是在此之前,我们先了解下 Feign 的自定义日志级别。
Feign 的自定义日志级别
级别 | 打印内容 |
---|---|
NONE(默认值) | 不记录任何日志 |
BASIC | 仅记录请求方法、URL、响应状态码以及执行时间 |
HEADERS | 记录 BASIC 级别的基础上,记录请求和响应的 header |
FULL | 记录请求和响应的 header、body 和元数据 |
Feign 的自定义日志级别可以通过 Java 代码方式或配置属性方式来实现,下面我们先介绍下代码的实现方式
代码配置方式
编写一个 Configuration 的类
public class UserFeignConfiguration {
@Bean
public Logger.Level level() {
// 生产上不建议使用FULL,这样会产生大量的日志,影响性能的同时还不好定位问题。
// 建议使用 BASIC
return Logger.Level.FULL;
}
}
然后在对应的 Feign 接口设置 Configuration 类
@FeignClient(name = "user", configuration = UserFeignConfiguration.class)
public interface UserFeignClient {
@GetMapping("/users/{id}")
UserDto findById(@PathVariable Integer id);
}
最后还要将 Feign接口类的全路径设置在 yml 文件里面
logging:
level:
# Feign接口类的全路径
# Feign的日志级别是建立在Feign的接口 debug 级别之上的
com.example.article.feignclient.UserFeignClient: debug
当调用接口时,输出日志结果如下
[UserFeignClient#findById] <--- HTTP/1.1 200 (794ms)
[UserFeignClient#findById] content-type: application/json;charset=UTF-8
[UserFeignClient#findById] date: Mon, 29 Aug 2022 10:56:27 GMT
[UserFeignClient#findById] transfer-encoding: chunked
[UserFeignClient#findById]
[UserFeignClient#findById] {"id":1,"username":"张三","createTime":"2022-08-25T17:17:04.000+0000","updateTime":"2022-08-25T17:17:04.000+0000"}
[UserFeignClient#findById] <--- END HTTP (180-byte body)
这样,通过代码来设置 Feign 的日志自定义级别方式就配置好了。但是这样,并不是完美的解决方案,就相当于每次新建一个 Feign 接口,就要编写一个对应的 xxxFeignConfiguration 类,然后在 Feign 接口上指定,这样下来太繁琐了,下面看下全局的代码配置方式:
不需要在 每个 Feign 接口上面都要配置下
configuration = UserFeignConfiguration.class
,我们只需要在 Application 启动类上面,指定@EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class)
,注:这里将 UserFeignConfiguration 已经更名为 GlobalFeignConfiguration@SpringBootApplication
@EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
属性配置方式
在 application.yml 加入只需要配置以下的属性既可以实现 Feign 的自定义级别
feign:
client:
config:
# 微服务名称
user:
loggerLevel: full
同理,yml 文件也支持 全局的属性配置方式
feign:
client:
config:
# 全局配置(default 默认就是适用于全部微服务)
default:
loggerLevel: full
Feign的多参数请求构造
GET 请求
请求多参数的URL,如请求地址为 http://www.xxx.me/admin/user/get?username=张三&school=阳光小学&birthDay=2012-08-01
,SpringCloud 为 Feign 整合了 SpringMVC 的注解支持
@SpringQueryMap
注解@FeignClient("user")
public interface UserFeignClient {
@RequestMapping(value = "/get", method = RequestMethod.GET)
public User get(@SpringQueryMap User user);
}
@RequestParam
注解(表单传参)@FeignClient("user")
public interface UserFeignClient {
@RequestMapping(value = "/get", method = RequestMethod.GET)
public User get(@RequestParam("username") String username, @RequestParam("school") String school, @RequestParam("birthDayDay") String birthDay);
}
@PathVariable
注解(URL携带参数)@FeignClient("user")
public interface UserFeignClient {
@RequestMapping(value = "/get", method = RequestMethod.GET)
public User get(@PathVariable("username") String username, @PathVariable("school") String school, @PathVariable("birthDayDay") String birthDay);
}
POST 请求
Feign 默认的传参方式就是 JSON 传参(@RequestBody
),因此定义接口的时候可以不用@RequestBody
注解标注,但为了开发规范,建议加上
@RequestBody
注解@FeignClient("user")
public interface UserFeignClient {
@RequestMapping(value = "/post", method = RequestMethod.POST)
public User post(@RequestBody User user);
}
超时设置
我们在通过 Feign 去调用接口,难免会遇到超时的问题,我们可以在 yml 文件设置超时属性,防止系统抛出超时异常
feign:
client:
config:
# 全局配置(default 默认就是适用于全部微服务)
default:
connectTimeout: 100000
readTimeout: 100000
# 单独配置
user:
connectTimeout: 300000
readTimeout: 300000
Feign 性能优化
默认情况下,Feign 使用的是 UrlConnetcion 去请求,这种原生的请求方式一旦遇到高并发的情况下,响应会变得很慢,所以我们可以考虑加入连接池技术来优化性能,下面介绍下如何集成 Apache 下的 HttpClient 的连接池
加入 httpclient 依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
设置 yml 文件属性
feign:
# 这样就设置好了 feign 请求方式是 httpclient,而不是 UrlConnetcion
httpclient:
enable: true
# feign的最大连接数
max-connection: 200
# feign 单个路径的最大连接数
max-connections-per-route: 50
声明式HTTP客户端-Feign 使用入门详解的更多相关文章
- Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务
首先简单解释一下什么是声明式实现? 要做一件事, 需要知道三个要素,where, what, how.即在哪里( where)用什么办法(how)做什么(what).什么时候做(when)我们纳入ho ...
- spring cloud 声明式rest客户端feign调用远程http服务
在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...
- 3.【Spring Cloud Alibaba】声明式HTTP客户端-Feign
使用Feign实现远程HTTP调用 什么是Feign Feign是Netflix开源的声明式HTTP客户端 GitHub地址:https://github.com/openfeign/feign 实现 ...
- net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos
1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...
- SpringCloud学习笔记(9)----Spring Cloud Netflix之声明式 REST客户端 -Feign的使用
1. 什么是Feign? Feign是一种声明式.模板化的HTTP客户端,在SpringCloud中使用Feign.可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到 ...
- Spring 声明式事务与编程式事务详解
本文转载自IBM开发者论坛:https://developer.ibm.com/zh/articles/os-cn-spring-trans 根据自己的学习理解有所调整,用于学习备查. 事务管理对于企 ...
- SpringCloud学习笔记(10)----Spring Cloud Netflix之声明式 REST客户端 -Feign的高级特性
1. Feign的默认配置 Feign 的默认配置 Spring Cloud Netflix 提供的默认实现类:FeignClientsConfiguration 解码器:Decoder feignD ...
- Spring Cloud官方文档中文版-声明式Rest客户端:Feign
官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...
- SpringCloud 源码系列(6)—— 声明式服务调用 Feign
SpringCloud 源码系列(1)-- 注册中心 Eureka(上) SpringCloud 源码系列(2)-- 注册中心 Eureka(中) SpringCloud 源码系列(3)-- 注册中心 ...
随机推荐
- vue大型电商项目尚品汇(后台篇)day05
今天继续是对后台管理部分的一个操作,但是快要结束了,今天结束,明天会进入一个从Vue以来,另外一个名声显著的东西了,一只耳闻从未见识,而且十分的炫酷 他就是------数据可视化Echarts,迫不及 ...
- 毕设着急了吧?Python股票数据分析,制作动态柱状图
写在前面的一些屁话: 雪球成立于 2010 年,是北京雪球信息科技有限公司旗下推出的投资者社区.雪球一直致力于为中国投资者提供跨市场(沪深.香港.美国),跨品种(股票.基金.债券等)的数据查询.资讯获 ...
- 异常注意事项_多异常的捕获处理和异常注意事项_finally有return语句
异常注意事项_多异常的捕获处理 多个异常使用捕获又该如何处理呢? 1. 多个异常分别处理 2. 多个异常一次捕获,多次处理 3. 多个异常一次捕获一次处理 public class Demo01Exc ...
- NuGetTools:批量上传、删除和显示NuGet包
快照 前言 NuGet是.NET开发必不可少的包管理工具,在日常更新版本过程中,可能需要批量发布 NuGet 包,也不可避免需要发布一些测试的包,后期想将这些测试或者过期的包删除掉.nuget.org ...
- 挑战30天写操作系统-day3-进入32位模式并导入C语言
目录 1.制作真正的IPL IPL:启动区,启动程序装载器完整代码: ; haribote-ipl ; TAB=4 CYLS EQU 10 ; 声明CYLS=10 ORG 0x7c00 ; 指明程序装 ...
- Markdown 的基本使用
Markdown基本语法 1.标题 //标题的写法 #一级标题 ##二级标题 ###三级标题 //以此类推... 效果: 一级标题 二级标题 三级标题 2.分割线 使用三个或以上-或*表示,并且改行不 ...
- Druid 查询超时配置的探究 → DataSource 和 JdbcTemplate 的 queryTimeout 到底谁生效?
开心一刻 昨晚跟我妈语音 妈:我年纪有点大了,想抱孩子了 我:妈,我都多大了,你还想抱我? 妈:我想抱小孩,谁乐意抱你呀! 我:刚好小区有人想找月嫂,要不我帮你联系下? 妈:你给我滚 然后她直接把语音 ...
- MyBatis-Plus联表查询的短板,终于有一款工具补齐了
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. mybatis-plus作为mybatis的增强工具,它的出现极大的简化了开发中的数据库操作,但是长久以来,它的 ...
- C++ 处理类型名(typedef,auto和decltype)
随着程序越来越复杂,程序中用到的类型也越来越复杂,这种复杂性体现在两个方面.一是一些类型难于"拼写",它们的名字既难记又容易写错,还无法明确体现其真实目的和含义.二是有时候根本搞不 ...
- python 可变、不可变类型、深拷贝、浅拷贝理解
简介 python中数据分为可变类型,不可变类型.不同的数据类型影响着不同情况下的深浅拷贝. 下面则将简要介绍一下 可变类型 当某个数据的值发生改变时,它对应的内存地址不发生改变,常见的有列表.字典. ...