Feign 使用篇

news2024/12/24 10:25:54

Feign是一个声明式的HTTP客户端工具,它简化了在分布式系统中进行服务间通信的过程。开发人员可以使用Feign来定义接口,然后通过该接口来调用远程服务,就像调用本地方法一样简单。

目录

    • Feign的一些关键特性和概念:
    • openfeign 对比 feign
      • Feign
      • OpenFeign
      • 安装
        • Maven安装引入
        • 配置
      • java config 配置RestTemplate
        • 超时配置
        • 日志配置
        • 开启GZIP
      • 使用
        • 在`auth` service中定义userClient
        • 在`order` service的`helloController`中调用UserClient
      • Feign 拦截器
    • 总结:
      • feign底层会调用restTemplate吗?
      • feign底层可以使用哪几种http框架?

Feign的一些关键特性和概念:

  1. 声明式API

    • 使用Feign,你只需要创建一个Java接口,并使用注解来描述HTTP请求的格式、路径、参数等信息。
    • Feign会根据这些注解自动生成一个HTTP客户端的实现,你可以直接调用这个接口来发送HTTP请求。
  2. 与Spring Cloud集成

    • Feign是Spring Cloud生态系统的一部分,与其他Spring Cloud组件(如Eureka、Ribbon、Hystrix等)无缝集成,可以充分发挥微服务架构的优势。
  3. 负载均衡

    • Feign集成了Ribbon,可以利用Ribbon的负载均衡功能,将请求分发到多个服务实例中。
  4. 服务熔断

    • Feign集成了Hystrix,可以通过在Feign接口上添加@HystrixCommand注解来实现服务的熔断和降级。
  5. 动态URL和参数处理

    • Feign允许在运行时动态改变请求的URL,也可以使用@RequestParam等注解来处理请求的参数。
  6. 多继承

    • OpenFeign扩展了Feign,支持多继承,可以继承多个Feign接口,实现接口的组合。
  7. 日志和日志级别

    • Feign提供了日志级别的控制,可以用于调试和监控请求。
  8. 请求和响应拦截

    • 可以使用RequestInterceptorResponseInterceptor来拦截请求和响应,可以用于添加认证信息、记录日志等操作。

总的来说,Feign是一个强大的工具,使得在微服务架构中进行服务间通信变得非常简单和便捷。通过声明式的API和集成的特性,开发人员可以更加专注于业务逻辑的实现,而不需要手动处理HTTP请求和响应的细节。同时,通过集成Ribbon和Hystrix,Feign也提供了负载均衡和服务熔断的支持,使得微服务架构变得更加健壮和可靠。

openfeign 对比 feign

Feign和OpenFeign都是用于简化在微服务架构中进行服务间通信的工具,它们都属于Spring Cloud生态系统的一部分。

Feign

Feign是Netflix开发的一个声明式的HTTP客户端,它使得编写HTTP客户端变得非常简单。在Feign中,你只需要创建一个接口,然后使用注解来描述HTTP请求的格式、路径、参数等信息,Feign会自动帮你生成实现这个接口的HTTP客户端。

Feign的特点:

  • 声明式的API:通过接口定义,使得调用远程服务的代码看起来像调用本地方法一样简单。
  • 集成了Ribbon:可以使用Ribbon的负载均衡功能。
  • 集成了Hystrix:可以使用Hystrix来实现服务的熔断和降级。

OpenFeign

OpenFeign是Spring Cloud对Feign进行了封装和扩展,提供了一些额外的功能和特性。

OpenFeign相比原始的Feign具有一些优势:

  • 支持Spring MVC注解:可以使用Spring MVC的注解,如@RequestMapping@RequestParam等,使得接口的定义更加灵活。
  • 支持多继承:可以继承多个Feign接口,实现接口的组合。
  • 支持动态URL:可以在运行时动态改变请求的URL。

总的来说,OpenFeign是对Feign的增强和扩展,提供了更多的灵活性和便利性,使得微服务之间的通信更加方便和高效。

在实际项目中,如果你使用了Spring Cloud,通常会优先选择使用OpenFeign来简化服务间的通信。

安装

Maven安装引入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.jorian.framework</groupId>
    <artifactId>j-cloud-consumer-feign</artifactId>
    <version>1.0.0</version>
    <name>j-cloud-consumer-feign</name>
    <description>Demo project for Spring Boot</description>
 
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <cloud.version>Dalston.SR1</cloud.version>
    </properties>
    <dependencies>
        <!-- hystrix断路器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <!--LOMBOK-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
            <scope>provided</scope>
        </dependency>
        <!-- eureka 配置中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <!-- fegin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- boot-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
 
    <!-- dependency management -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
</project>
配置

启动类上上注解

package cn.jorian.framework;
 
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
 
 
/**
 * @author jorian
 */
@SpringCloudApplication
@EnableEurekaClient // 表明这是一个eureka客户端
@EnableFeignClients(basePackages = "cn.jorian.*") //开启feign
public class JCloudConsumerFeignApplication {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SpringApplication.run(JCloudConsumerFeignApplication.class, args);
    }
 
}

feign 可以结合nacos、eureka等注册中心使用。当然也可以不适用注册中心,直接在feignClient上指定url来调用,非常的灵活。

java config 配置RestTemplate

RestTemplate配置

@Bean
@LoadBalanced
private RestTemplate restTemplate () {
	return new RestTemplate();
}
超时配置
import static java.util.concurrent.TimeUnit.MILLISECONDS;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    public feign.Request.Options getFeignRequestOptions() {
        return new feign.Request.Options(5000, MILLISECONDS, 3000, MILLISECONDS, true);
    }
}

也可以通过yml进行配置

feign:
  client:
    config:
      default: # 可以指定具体某个SERVICE,可以替换成service name
        connectTimeout: 5000
        readTimeout: 3000
日志配置

application.yml文件中设置日志级别,这个是应用日志的级别要和feign的日志级别配合使用。

logging:
  level:
    com.csdnblogs.javalouvre.api: debug

application.yml配置feign日志级别,需要指定针对服务名称

feign:
  client:
    config:
      stock-service: # 具体的servicename,可以替换成default全局生效
        loggerLevel: FULL

也可以使用javaconfig,下面这个也是全局生效的配置

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

在这里插入图片描述

开启GZIP
feign:
    compression:
        request:
            enabled: true
            mime-types: text/xml,application/xml,application/json # 配置压缩支持的MIME TYPE
            min-request-size: 2048  # 配置压缩数据大小的下限
        response:
            enabled: true # 配置响应GZIP压缩

使用

假入有一个auth service 和一个 order server 现在order service要调用 auth service的UserClient

auth service中定义userClient
package cn.jorian.framework.service;
 
 
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
/**
 * 这个接口相当于把原来的服务提供者项目当成一个Service类
 * @author jorian
 *
 */
@FeignClient("PROVIDER-USER") // ①
public interface UserClient {
 
        /**
         * Feign中没有原生的@GetMapping/@PostMapping/@DeleteMapping/@PutMapping,要指定需要用method进行
         *
         *
         * 接口上方用requestmapping指定是服务提供者的哪个controller提供服务
         */
        @RequestMapping(value="/user/sayHello",method=RequestMethod.GET)
        public String sayHello();
 
        @RequestMapping(value="/user/sayHi",method=RequestMethod.GET)
        public String sayHi();
 
        @RequestMapping(value="/user/sayHaha",method=RequestMethod.GET)
        public String sayHaha();
}

① @FeignClient value填写的是服务的名称,feign底层调用的时候会根据服务名称去找eureka、nacos注册列表根据服务名找到注册的实例,拼接成http url进行请求。

order service的helloController中调用UserClient
package cn.jorian.framework.controller;
 
import cn.jorian.framework.service.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class Hellocontroller {

    @Autowired
    private UserClient feignClient;
    /**
     * 此处的mapping是一级controller,调用方法里边绑定了二级的conroller,相当于用http完成一次转发
     * @return
     */
    @GetMapping("/hello")
    public String hello(){
        return feignClient.sayHello();
    }
 
    @GetMapping("/hi")
    public String hi(){
        return feignClient.sayHi();
    }
 
    @GetMapping("/haha")
    public String haha(){
        return feignClient.sayHaha();
    }
    
}

以一个实例来验证说明效果,自定义三个 RequestInterceptor

class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("user", "myuser1");
        requestTemplate.header("password", "mypassword");
    }
}

@FeignClient 中可以指定一个拦截器和feign配置

@FeignClient(
        name = "test-service",
        url = "http://localhost:8080/feign/server/",
        configuration = {FeignInterceptor.class,TestConfiguration.class},
        fallback = TestService.DefaultFallback.class
)

Feign 拦截器

RequestInterceptor是拦截器,可以在发送前做一些处理,比如统一添加header信息。每一类中的requestInterceptors可以存储多个拦截器,拦截器并非覆盖的效果,而是链式追加的效果;从执行顺序来看优先级是:1 > 2 > 3,即先执行配置类中指定的拦截器,然后是配置文件中指定的全局拦截器,最后是配置文件中指定的专属拦截器。

需特别注意:RequestInterceptor的实现类(例如 RI-A,RI-B)上如果添加了@Component注解,就都会被扫描识别到,并被追加到第一类的requestInterceptors列表中;倘若不小心 RI-A 还在第 2 类中又被指定了,则还会将拦截器 RI-A 追加在第二类的requestInterceptors列表中,结果是会 RI-A 总计会执行 2 次;若也在第三类中指定 RI-A,则 RI-A 也在其列表中追加,结果是 RI-A 总计会执行 3 次。

总结:

feign底层会调用restTemplate吗?

是的,Feign在底层使用了RestTemplate来发送HTTP请求。RestTemplate是Spring框架提供的一个用于发送HTTP请求的工具类,它提供了许多便捷的方法来处理HTTP请求和响应。

Feign通过将接口的方法映射到HTTP请求,使得你可以以一种声明式的方式调用远程服务。Feign会将这些方法调用转换为相应的HTTP请求,并使用RestTemplate来实际发送请求。

然而,需要注意的是,随着Spring Cloud的发展,RestTemplate正在逐渐被WebClient取代。WebClient是一个非阻塞、响应式的HTTP客户端,适用于构建响应式的、高性能的分布式系统。因此,如果你使用了Spring Cloud的最新版本,可能会更倾向于使用WebClient而不是RestTemplate。

如果你使用的是旧版本的Spring Cloud或者有特定的需求需要使用RestTemplate,那么Feign将会继续使用它作为发送HTTP请求的底层工具。

feign底层可以使用哪几种http框架?

okHttp/apache httpClient/HttpUrlConnection

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

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

相关文章

算法:O(1) 时间插入、删除和获取随机元素---哈希表+动态数组

1、题目&#xff1a; 实现RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时&#xff0c;向集合中插入该项&#xff0c;并返回 true &#xff1b;否则&#xff0c;返回 false 。bool remove(int val) 当元素…

基于jquery开发的Windows 12网页版

预览 https://win12.gitapp.cn 首页代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"refresh" content"0;urldesktop.html" /> <meta name"viewport&…

上海亚商投顾:沪指放量涨1.55% AI概念股全线爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数9月22日放量反弹&#xff0c;沪指午后涨超1%&#xff0c;重返3100点上方&#xff0c;创业板指涨超2%…

通过monorepo管理多个子项目

通过monorepo管理多个子项目 1. Monorepo模式 在Monorepo 模式下,根目录通常不建议直接安装依赖,而是通过工作区(workspaces)来管理依赖。 但是在一些情况下,在根目录安装一些共享依赖也是可以的。 在根目录安装开发相关的依赖 如TypeScript, ESLint, Jest等。这些可以被所有…

手把手教 - 开源库 libmodbus 的RTU-Master 的使用笔记

测试环境&#xff1a;基于nuc980开发板 Linux信息&#xff1a;Linux buildroot 4.4.289 #8 PREEMPT Thu Sep 21 14:29:45 CST 2023 armv5tejl GNU/Linux 目录&#xff1a; 一、libmodbus 库简介 二、下载链接 三、移植准备 四、移植过程和完整代码 五、测试结果 一、libmodbus …

虚拟机数据恢复:Stellar Data Recovery for Virtual Machine

虚拟机数据恢复-----Crack Version Stellar Data Recovery for Virtual Machine 软件可从 VMware (.vmdk)、ORACLE (.vdi) 和 Microsoft (.vhd) 虚拟映像文件中恢复丢失和删除的数据。 从 VMDK、VDI 和 VHD 虚拟映像文件中恢复数据提供原始恢复选项来恢复数据从已删除或无法识…

太阳能供电模块

基于Solar Cell的锂电池充放电模块 由于一些需求&#xff0c;最近做了一款基于太阳能的锂电池充放电模块。该模块能够利用太阳能为锂电池充电和为负载提供5V的电压&#xff0c;在太阳能不充足的条件下&#xff0c;由锂电池提供需要的能量。 主要思路是将太阳能板获得的能量存储…

嵌入式Linux学习(1)——通信总线协议简介

目录 一. UART 1.1 单工/双工通信 ​编辑 1.2 UART帧格式 1.2.1 Q/A 1.3 UART硬件结构 二. 基于UART的协议 2.1 RS232 2.1.1 RS232协议存在的问题 2.2 RS485 2.2.1 差分信号 2.2.2 RS485优势 三. IIC 3.1 通信过程 3.2 IIC总线寻址 3.3 IIC总线信号 3.3.1 起始…

USB转2路RS422串口

基于USB转2路串口芯片CH342&#xff0c;可以为各类主机扩展出2个独立的串口。CH342芯片支持使用操作系统内置的CDC串口驱动&#xff0c;也支持使用厂商提供的VCP串口驱动程序&#xff0c;可支持Windows、Linux、Android、macOS等操作系统。因CDC类协议和类驱动的原因&#xff0…

多通道振弦数据记录仪在预防地质灾害中的重要性

多通道振弦数据记录仪在预防地质灾害中的重要性 地质灾害是指在地表或岩体内部发生的、由地质原因引起的、对人类生命、财产和环境安全造成威胁或损害的各种灾害。地质灾害的预测和预防对于保障人民生命财产安全、维护社会稳定和可持续发展具有重要的意义。而多通道振弦数据记…

九章云极DataCanvas公司智算中心正式落地

为构建全社会数字经济提供高效的计算底座&#xff0c;向全市场提供高效高速的智算能力&#xff0c;为用户提供算法算力一体化的服务&#xff0c;九章云极DataCanvas公司智算中心落户安徽省马鞍山市&#xff0c;并于9月4日成功举行“马鞍山市花山区垂直行业人工智能大模型训练算…

Easysearch 压缩功能的显著提升:从 8.7GB 到 1.4GB

引言 在海量数据的存储和处理中&#xff0c;索引膨胀率是一个不可忽视的关键指标。它直接影响了存储成本和查询性能。近期&#xff0c;Easysearch 在这方面取得了显著的进展&#xff0c;其压缩功能的效果远超过了之前的版本。本文将详细介绍这一进展。 Easysearch 各版本压缩性…

大屏大概是怎么个开发法(前端)

写在前面&#xff0c;博主是个在北京打拼的码农&#xff0c;从事前端工作5年了&#xff0c;做过十多个大大小小不同类型的项目&#xff0c;最近心血来潮在这儿写点东西&#xff0c;欢迎大家多多指教。 对于文章中出现的任何错误请大家批评指出&#xff0c;一定及时修改。有任何…

Vue 使用vue完成登录+注册前后端交互的实现

前言&#xff1a; 我们上一篇已经讲解了如何使用vue去构建一个SPA项目。今天我们就在昨天的基础之上完成登录注册前后端交互的实现。 我们使用Vue构建登录注册前后端交互的实现有以下好处、意义和效率&#xff1a; 好处&#xff1a; 响应式渲染&#xff1a;Vue采用了虚拟DOM技术…

Coupang走什么物流?Coupang火箭颜色什么意思?——站斧浏览器

coupang物流包括三个选项&#xff0c;分别是“自发货”“CGF”和“CGF LITE”&#xff0c;怎么选择才对自己最有利的呢&#xff1f;coupang火箭颜色什么意思&#xff1f;一起来了解下吧。 coupang走什么物流? ① 自发货 也就是卖家自己找第三方货代公司帮你发货&#xff0c…

C++ - map 和 set 的模拟实现 - 红黑树当中的仿函数 - 红黑树的迭代器实现

简单了解map 和 set 的实现 首先我们要知道&#xff0c;map 和 set 的底层就是 红黑树&#xff0c;但是 STL 当中 &#xff0c;map 和 set 并不是我们想象的&#xff0c;直接使用一个 pair 对象来存储一个 key-value 或者 是 一个 key。具体如下所示&#xff1a; set&#xff…

大数据Flink(八十九):Temporal Join(快照 Join)

文章目录 Temporal Join(快照 Join) Temporal Join(快照 Join) Temporal Join 定义(支持 Batch\Streaming):Temporal Join 在离线的概念中其实是没有类似的 Join 概念的,但是离线中常常会维护一种表叫做 拉链快照表,使用一个明细表去 join 这个 拉链快照表 的 join …

介绍 Docker 的基本概念和优势V2.0

介绍 Docker 的基本概念和优势V2.0 一、Docker 的基本概念1.1 Docker 是什么&#xff1f;1.2 Docker 的组成部分1.3 Docker 的基本概念 二、Docker 的优势1. 轻量级&#xff1a;2. 可移植性&#xff1a;3. 自包含&#xff1a;4. 隔离性&#xff1a;5. 可扩展性&#xff1a;6. 易…

SpringBoot 学习(八)异步任务,邮件发送和定时执行

8. 异步任务 (1) 开启异步注解 // 启动类 EnableAsync SpringBootApplication public class TestApplication {public static void main(String[] args) {SpringApplication.run(TestApplication.class, args);}}(2) 声明异步方法 // service Service public class AsyncSer…