什么是 OpenFeign

OpenFeign (以下统一简称为 Feign) 是 Netflix 开源的声明式 HTTP 客户端,集成了 Ribbon 的负载均衡、轮询算法和 RestTemplate 的 HTTP 调用等特性,并对其进行封装,使用者只需要在此基础上,定义一个接口,并在接口上标注一个 FeignClient ,便可以实现 HTTP 远程调用,上面的声明式 HTTP 如何理解,可以理解为

​ 只需要声明一个接口,Feign 就会通过你定义的接口,自动给你构造请求的目标地址并请求。

下面介绍下如何在项目中集成 Feign 组件,只需要遵循 SpringBoot 开发三板斧(1、加依赖,2、加注解,3、加配置)即可

环境准备

  1. 加依赖 openfeign

    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
  2. 加注解 @EnableFeignClients

    @SpringBootApplication
    @EnableFeignClients
    public class Application {
    public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
    }
  3. 加配置(由于 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 代码方式或配置属性方式来实现,下面我们先介绍下代码的实现方式

代码配置方式

  1. 编写一个 Configuration 的类

    public class UserFeignConfiguration {
    @Bean
    public Logger.Level level() {
    // 生产上不建议使用FULL,这样会产生大量的日志,影响性能的同时还不好定位问题。
    // 建议使用 BASIC
    return Logger.Level.FULL;
    }
    }
  2. 然后在对应的 Feign 接口设置 Configuration 类

    @FeignClient(name = "user", configuration = UserFeignConfiguration.class)
    public interface UserFeignClient {
    @GetMapping("/users/{id}")
    UserDto findById(@PathVariable Integer id);
    }
  3. 最后还要将 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 的注解支持

  1. @SpringQueryMap 注解

    @FeignClient("user")
    public interface UserFeignClient {
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public User get(@SpringQueryMap User user);
    }
  2. @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);
    }
  3. @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注解标注,但为了开发规范,建议加上

  1. @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 的连接池

  1. 加入 httpclient 依赖

    <dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
    </dependency>
  2. 设置 yml 文件属性

    feign:
    # 这样就设置好了 feign 请求方式是 httpclient,而不是 UrlConnetcion
    httpclient:
    enable: true
    # feign的最大连接数
    max-connection: 200
    # feign 单个路径的最大连接数
    max-connections-per-route: 50

声明式HTTP客户端-Feign 使用入门详解的更多相关文章

  1. Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务

    首先简单解释一下什么是声明式实现? 要做一件事, 需要知道三个要素,where, what, how.即在哪里( where)用什么办法(how)做什么(what).什么时候做(when)我们纳入ho ...

  2. spring cloud 声明式rest客户端feign调用远程http服务

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...

  3. 3.【Spring Cloud Alibaba】声明式HTTP客户端-Feign

    使用Feign实现远程HTTP调用 什么是Feign Feign是Netflix开源的声明式HTTP客户端 GitHub地址:https://github.com/openfeign/feign 实现 ...

  4. net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos

    1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...

  5. SpringCloud学习笔记(9)----Spring Cloud Netflix之声明式 REST客户端 -Feign的使用

    1. 什么是Feign? Feign是一种声明式.模板化的HTTP客户端,在SpringCloud中使用Feign.可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到 ...

  6. Spring 声明式事务与编程式事务详解

    本文转载自IBM开发者论坛:https://developer.ibm.com/zh/articles/os-cn-spring-trans 根据自己的学习理解有所调整,用于学习备查. 事务管理对于企 ...

  7. SpringCloud学习笔记(10)----Spring Cloud Netflix之声明式 REST客户端 -Feign的高级特性

    1. Feign的默认配置 Feign 的默认配置 Spring Cloud Netflix 提供的默认实现类:FeignClientsConfiguration 解码器:Decoder feignD ...

  8. Spring Cloud官方文档中文版-声明式Rest客户端:Feign

    官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...

  9. SpringCloud 源码系列(6)—— 声明式服务调用 Feign

    SpringCloud 源码系列(1)-- 注册中心 Eureka(上) SpringCloud 源码系列(2)-- 注册中心 Eureka(中) SpringCloud 源码系列(3)-- 注册中心 ...

随机推荐

  1. Ubuntu-apt-get出错

    ubuntu apt-get的时候出现: E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission ...

  2. Mac安装Brew包管理系统

    Mac安装Brew包管理系统 前言 为什么需要安装brew 作为一个开发人员, 习惯了使用centos的yum和ubuntu的apt, 在mac中有没有这两个工具的平替? 有, 就是Brew. Bre ...

  3. ssh-免密钥登陆

    实现openssh免密钥登陆(公私钥验证) 在主机A上,通过root用户,使用ssh-keygen生成的两个密钥:id_rsa和id_rsa.pub 私钥(id_rsa)保存在本地主机,公钥(id_r ...

  4. 【数据库Mysql 查询当前时间,年月日】

    1.本年份 SELECT YEAR(now()) SELECT DATE_FORMAT(NOW(), '%Y') 2.本月份(例如:1.01.January) SELECT MONTH(now()) ...

  5. -bash: /usr/local/maven/apache-maven-3.8.1/bin/mvn: 权限不够

    chmod a+x /usr/local/maven/apache-maven-3.8.1/bin/mvn

  6. 52 条 SQL 语句性能优化策略,建议收藏

    本文会提到 52 条 SQL 语句性能优化策略. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引. 2.应尽量避免在where子句中对字段进行nul ...

  7. ctfshow的web入门171

    web入门171 看到这个查询语句,我们可以进行相关操作 $sql = "select username,password from user where username !='flag' ...

  8. Tomcat7下使用Log4j接管catalina.out日志文件

    Tomcat7下使用Log4j接管catalina.out日志文件    摘要 Tomcat7下使用Log4j接管catalina.out日志文件生成方式,按天存放,解决catalina.out日志文 ...

  9. 002面试题_Switch...case的数据

    1.byte 2.short 3.int 4.char 5.String 6.枚举

  10. Odoo14 设置Binary字段默认值

    1 # Odoo 中的附件也就是Binary字段都是经过特殊处理的 2 # 首先是上传的时候会进行base64编码后再上传到服务器 3 # 服务器进行压缩存放在odoo文件仓库中 4 # 每个odoo ...