RPC 框架 openfeign 介绍和学习使用总结

一、基本概念

RPC

远程过程调用Remote Procedure Call)的缩写形式

Birrell 和 Nelson 在 1984 发表于 ACM Transactions on Computer Systems 的论文《Implementing remote procedure calls》对 RPC 做了经典的诠释。

RPC 是指计算机 A 上的进程,调用另外一台计算机 B 上的进程,其中 A 上的调用进程被挂起,而 B 上的被调用进程开始执行,当值返回给 A 时,A 进程继续执行。

调用方可以通过使用参数将信息传送给被调用方,而后可以通过传回的结果得到信息。而这一过程,对于开发人员来说是透明的。

openfeign 和 feign

OpenFeign 是 Spring Cloud 在 Feign 的基础上支持了SpringMVC的注解,如@RequesMapping等等。

OpenFeign 的 @FeignClient 可以解析 SpringMVC 的 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

Feign 是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。

Feign的使用方式是使用Feign的注解定义接口,调用这个接口就可以调用服务注册中心的服务。

OpenFeign 的设计宗旨是简化 Java Http 客户端的开发。

FeignrestTemplate 的基础上做了进一步的封装,由其来帮助我们定义和实现依赖服务接口的定义。
在OpenFeign的协助下,我们只需创建一个接口并使用注解的方式进行配置(类似于Dao接口上面的Mapper注解)即可完成对服务提供方的接口绑定,大大简化了Spring cloud Ribbon的开发,自动封装服务调用客户端的开发量。

OpenFeign集成了Ribbon,利用ribbon维护了服务列表,并且通过ribbon实现了客户端的负载均衡。
与 ribbon 不同的是,通过OpenFeign只需要定义服务绑定接口且以申明式的方法,优雅而简单的实现了服务调用。

二、基本使用

依赖

依赖于springMVC 的 web 服务,或者直接使用 spring-boot 的 spring-boot-starter-web 系列基础包。
web 等基础系列包

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

feign 基本

${openfeign.version} 可以自定替换版本,这里示例用 2.2.2.RELEASE

		<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>${openfeign.version}</version></dependency><!-- okhttp openfeign远程调用依赖的HttpClient --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId><version>${feign-okhttp.version}</version></dependency>

如果出现引入后出现个别问题可以尝试去除如下

		<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>${openfeign.version}</version><exclusions><exclusion><artifactId>guava</artifactId><groupId>com.google.guava</groupId></exclusion></exclusions></dependency>

服务注册中心的依赖,一般场景不需要(使用分布式场景时考虑)

<!--服务发现客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

启用

spring-boot 需要在启动类上添加注解 @EnableFeignClients
位置与 @SpringBootApplication@EnableTransactionManagement@ComponentScan 等在启动类上的注解 位置一致
例如:
在这里插入图片描述

  1. 若同时考虑分布式场景,即 cloud 自带的 eureka
    在相同的位置增加 注解 @EnableEurekaClient
    同时可以在yml 或 properties 配置如下参考
eureka:client:serviceUrl:#服务中心地址defaultZone: http://localhost:8881/eureka/,http://localhost:8882/eureka/ instance:#显示ip地址prefer-ip-address: true 

超时时间设置

默认超时时间为 1s

feign:client:config:default:readTimeout: ${RPC_TIME_OUT:600000}connectTimeout: ${RPC_TIME_OUT:600000}

也可以配置

# OpenFeign 默认支持 ribbon
ribbon:# 建立连接所用的时间,两端连接所用的时间ReadTimeout: 6000# 建立连接后从服务器读取到可用资源所用时间ConnectTimeout: 6000

创建请求

大致可以参考如下示例:

import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;@FeignClient(name = "XxxxClient", url = "${xxxx.server}")
public interface XxxxClient {@PostMapping("/test/create")XxxxxResult createXxxxxxx(@RequestBody XxxxxxxRequest body,@RequestHeader MultiValueMap<String, String> header);@PostMapping(value = "/test/check", consumes = "multipart/form-data")XxxxxResult importXxxxx(@RequestPart("file") MultipartFile file, @RequestParam Long id,@RequestHeader MultiValueMap<String, String> header);@PostMapping("/test/config")XxxxxResult xxxxxxConfig(@RequestParam Long id, @RequestBody JSONObject body,@RequestHeader MultiValueMap<String, String> header);@PostMapping("/test/xxxxxx")XxxxxResult xxxxxXxxxxxxxx(@RequestParam Long id, @RequestBody JSONObject body, @RequestHeader MultiValueMap<String, String> header);@GetMapping("/test/xxxx/{id}")XxxxxResult xxxxXxxxx(@PathVariable String id, @RequestHeader MultiValueMap<String, String> header);}

在上面的请求中添加请求头的方式

  1. 在请求注解中添加
@RequestMapping(value="/xxxxx/xxxxx",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test();
  1. 如上方直接在参数中增加,多个使用map ,也可以在单个参数前加 单个注解@RequestHeader(“xxxx”) 指定值

  2. 在方法上方使用注解

	@RequestMapping(value="/xxxx/xxxxx",method = RequestMethod.POST)@Headers({"Content-Type: application/json;charset=UTF-8"})List<String> test();
  1. 见下方拦截器中增加请求头

说明
1.其中 @FeignClient(name = “XxxxClient”, url = “${xxxxx.server}”)
url 中的 ${xxxxx.server} 为spring-boot 中 yml 或者 properties 中配置的地址,也可以直接写入地址 例如:http://localhost:8081/testapi

2.可以通过 @GetMapping@PostMapping 直接指定将要请求的方法是 GET 或者POST 等请求,同理 @RequestParam 指定普通请求入参, @RequestHeader 指定请求的请求的头内容, @PathVariable 指定路径参数,@RequestBody 指定 请求体内容, @RequestPart 指定文件类型

3.@GetMapping@PostMapping后面的路径 即为实际请求第三方或要请求的其他产品的路径

用法基本与书写普通的请求类似,具体实现通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务,只要我们指定基本的所有关键信息即可,换言之,只要知道我们要携带的信息,后续的实现写法基本固定,故此可以实现高度封装。

@SpringQueryMap注解:

spring cloud 项目使用 feign 时会发现一个问题,就是get方式无法解析对象参数
其实 feign 是支持对象传递的,但是必须是 Map 形式,而且不能为空,与spring在机制上不兼容,因此无法使用。

spring cloud 在 2.1.x版本 中提供了**@SpringQueryMap** 注解,可以传递对象参数,框架自动解析。

例如:

@GetMapping(value = "/test/xxxxxxXxxx")XxxxxResult xxxxXxxxXxX(@SpringQueryMap BookDto dto);

@FeignClient

@FeignClient 相关属性如下:

属性说明
name指定该类的容器名称,类似于@Service(容器名称)
url即要请求的地址,可以更改指定地址
decode404当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
configurationFeign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
fallback定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
fallbackFactory用于生成fallback类示例,通过这个属性可以实现每个接口通用容错逻辑,减少重复代码
path定义当前FeignClient的统一前缀,当我们项目中配置了server.context-path,server.servlet-path时使用

远程调用接口当中,一般我们称提供接口的服务为提供者,而调用接口的服务为消费者。
OpenFeign一定是用在消费者上。

feign 日志等级控制

Feign 提供了日志打印功能,我们可以通过配置不同级别来调整日志输出内容,从而了解 Feign 中 Http 请求的细节。

其实就是多了一个请求日志的输出控制方式。

日志级别

级别名说明
NONE默认等级,不显示任何日志;
BASIC仅记录请求方法、URL、响应状态码及执行时间;
HEADERS除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
FULL除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

具体配置方式见后面的其他配置说明示例。

三、配置类

1. RequestInterceptor

可以通过自定义某一个类实现接口 RequestInterceptor(feign.RequestInterceptor) 来完成发送请求前要做的操作,例如添加统一的请求头,拼接统一参数,替换路径等等操作

例如
该接口只有一个方法,通过接口的入参可以获取当前请求的一些信息,或者修改当前请求的一些信息

@Slf4j
public class FeignBasicRequestInterceptor implements RequestInterceptor {public FeignBasicRequestInterceptor() {}@Overridepublic void apply(RequestTemplate template) {// 可以通过获取不同的路径来确定当前请求的是那一个请求或者哪一类请求,来具体确定要执行怎样的操作// template.feignTarget().url()    获取当前请求基本路,即@FeignClient 中的url 基础路径// template.url()     获取定义请求方法时 getMapping或postMapping后的地址 // template.method()   请求的类型 GET 还是 POST// template.body()  请求体,可能为空则可以 new String(template.body()) 或给与默认值// template.headers() 请求的头信息// template.header(String name, String... values) 设置添加请求头,具体可以点击类查看源码// template.query(String name, Iterable<String> values) 设置增加query 参数}}

可能用到: 基础认证

template.header(HttpHeaders.AUTHORIZATION, okhttp3.Credentials.basic(ak, sk));

2. 指定配置类

即 上方 @FeignClient 属性中可以指定的配置类
不是必须的但可以指定,内部的几个类也可以按需增加,部分可以不要

MyX509TrustManager 为自定类,用于适配https 信任所有证书或者自定义,在后面提供定义的内容

import feign.Client;
import feign.Logger;
import feign.Retryer;
import feign.codec.Decoder;
import feign.optionals.OptionalDecoder;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.ssl.SSLContexts;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;import static org.apache.http.conn.ssl.SSLConnectionSocketFactory.TLS;@Slf4j
@Configuration
class FeignConfiguration {@Autowiredprivate ObjectFactory<HttpMessageConverters> messageConverters;// OkHttpClient 替代原有的client,可以不替代@Beanpublic Client feignClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {SSLContext sslContext =SSLContexts.custom().loadTrustMaterial(null, (chain, authType) -> true).setProtocol(TLS).build();SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();OkHttpClient okHttpClient = new OkHttpClient.Builder().hostnameVerifier(NoopHostnameVerifier.INSTANCE).sslSocketFactory(sslSocketFactory, new MyX509TrustManager()).build();return new feign.okhttp.OkHttpClient(okHttpClient);}@Bean// 与上方加的配置类名称一致public FeignBasicRequestInterceptor basicAuthRequestInterceptor() {return new FeignBasicRequestInterceptor();}@Bean// 日志等级 上方日志等级中提及到的Logger.Level feignLoggerLevel() {return Logger.Level.FULL;}@Bean// 重试Retryer feignRetryer() {return Retryer.NEVER_RETRY;}@Bean// 结果解码类 new FeignResponseDecoder 为自己定义的解码类,见下方定义public Decoder feignDecoder() {return new OptionalDecoder(new FeignResponseDecoder(new SpringDecoder(this.messageConverters)));}
}

日志配置后的使用,需要在配置文件中指定某一接口或者类的等级

logging:level:# feign日志以什么级别监控哪个接口com.xxx.xxx.xxx.xxx: debug

MyX509TrustManager

(可选)需要可以仿照添加

import javax.net.ssl.X509TrustManager;/*** Https调用需要使用的TrustManager*/
public class MyX509TrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {// 什么都不做则信任所有 否则自定义内容}@Overridepublic void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {// 什么都不做则信任所有 否则自定义内容}@Overridepublic java.security.cert.X509Certificate[] getAcceptedIssuers() {return new java.security.cert.X509Certificate[]{};}
}

3. feign结果自定义解析类

import feign.FeignException;
import feign.Response;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;import java.io.IOException;
import java.lang.reflect.Type;/*** feign返回结果自定义解析**/
@Slf4j
public class FeignResponseDecoder extends ResponseEntityDecoder implements Decoder {public FeignResponseDecoder(Decoder decoder) {super(decoder);}@Overridepublic Object decode(Response response, Type type) throws IOException, FeignException {Object decode = super.decode(response, type);// type.getTypeName() 最上方创建请求时  定义的返回结果的toString 结果if (type.getTypeName().contains(XxxxxResult.class.getName())) {XxxxxResult result = (XxxxxResult) decode;// 检查返回是否为对方定义的成功码  如果不是抛出异常if (!"200".equals(result.getCode())) {// 可以使用自定义异常类 这里示例使用普通异常throw new Exception(result.getMessage());}}return decode;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ps:选区的基本操作

在 Photoshop 中&#xff0c;选区是为处理局部图像而自行定义的一个区域。 定义选区后&#xff0c;操作被限制在选区之内。选区周围显示的虚线边框&#xff0c;俗称“蚂蚁线”。 全选 Select All Ps菜单&#xff1a;选择/全部 Select/All 快捷键&#xff1a;Ctrl A 提示&#…

虚幻C++基础 day3

常见的游戏机制 Actor机关门 创建一个Actor类&#xff0c;添加两个静态网格与一个触发器 UBoxComponentUStaticMeshComponent 头文件&#xff1a; #include “Components/BoxComponent.h”#include “Components/StaticMeshComponent.h” TriggerDoor.h // Fill out your …

SPI简介及FPGA通用MOSI模块实现

简介 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外围设备接口&#xff09;通讯协议&#xff0c;是Motorola公司提出的一种同步串行接口技术。是一种高速、全双工、同步通信总线。在芯片中只占用四根管脚用来控制及数据传输。 优缺点&#xff1a; SPI通讯协…

yolov5 利用Labelimg对图片进行标注

首先打开yolov5-master&#xff0c;在data文件中新建一个文件夹来存放你需要跑的数据&#xff0c;例如我这次跑的是羽毛球&#xff0c;文件把文件取名为badminton。使用其他文件夹例如images也可以&#xff0c;就是跑多了以后不好整理&#xff0c;然后点击 选中刚刚你存放数据的…

iOS应用加固方案解析:ipa加固安全技术全面评测

​ 在移动应用开发领域&#xff0c;iOS应用的安全性一直备受关注。ipaguard作为一款专业的iOS应用加固方案&#xff0c;采用混淆加密技术&#xff0c;旨在保护应用免受破解、逆向和篡改等风险。本文将深入探讨ipaguard的产品功能、安全技术及其在iOS应用加固领域中的核心优势和…

从零开始搭建React+TypeScript+webpack开发环境-基于lerna的webpack项目工程化改造

项目背景 在实际项目中&#xff0c;我们的前端项目往往是一个大型的Webpack项目&#xff0c;结构较为复杂。项目根目录下包含了各种配置文件、源代码、以及静态资源&#xff0c;整体布局相对扁平。Webpack的配置文件分散在不同的部分&#xff0c;包括入口文件、输出目录、加载…

C#基于inpoutx64读写ECRAM硬件信息

inpoutx64.dll分享路径&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rOt0xtt9EcsrFQtf7S91ag 提取码&#xff1a;7om1 1.InpOutManager&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServi…

基于Docker容器DevOps应用方案

文章目录 基于docker容器DevOps应用方案环境基础配置1.所有主机永久关闭防火墙和selinux2.配置yum源3.docker的安装教程 配置主机名与IP地址解析部署gitlab.server主机1.安装gitlab2.配置gitlab3.破解管理员密码4.验证web页面 部署jenkins.server主机1.部署tomcat2.安装jenkins…

Ubuntu(WSL) mysql8.0.31 源码安装

要在 Ubuntu 上使用调试功能安装 MySQL 8.0 的源码&#xff0c;可以按照以下详细步骤进行操作&#xff1a; 1. 更新系统 首先&#xff0c;确保你的 Ubuntu 系统是最新的。运行以下命令更新系统软件包&#xff1a; sudo apt update sudo apt upgrade 2. 下载 MySQL 源码 访…

Wix使用velo添加Google ads tag并在form表单提交时向谷歌发送事件

往head里加代码时&#xff0c;不能看谷歌的代码&#xff0c;要看wix的代码&#xff0c;不然必定踩坑 https://support.wix.com/en/article/tracking-google-ads-conversions-using-wix-custom-code 这里的代码才对&#xff0c;因为wix搞了个velo&#xff0c;这个velo很傻x&am…

ChatGPT、GPT-4 Turbo接口调用

接口地址 https://chat.xutongbao.top/api/light/chat/createChatCompletion 请求方式 post 请求参数 model可选值&#xff1a; “gpt-3.5-turbo-1106”、 “gpt-3.5-turbo-16k” 、 “gpt-4”、“gpt-4-1106-preview”。 默认值为&#xff1a; “gpt-3.5-turbo-1106” to…

时间序列预测模型实战案例(十)(个人创新模型)通过堆叠CNN、GRU、LSTM实现多元预测和单元预测

本文介绍 本篇博客为大家讲解的是通过组堆叠CNN、GRU、LSTM个数&#xff0c;建立多元预测和单元预测的时间序列预测模型&#xff0c;其效果要比单用GRU、LSTM效果好的多&#xff0c;其结合了CNN的特征提取功能、GRU和LSTM用于处理数据中的时间依赖关系的功能。通过将它们组合在…

基于GCC的工具objdump实现反汇编

一&#xff1a;objdump介绍 在 Linux中&#xff0c;一切皆文件。 Linux 编程实际上是编写处理各种文件的代码。系统由许多类型的文件组成&#xff0c;但目标文件具有一种特殊的设计&#xff0c;提供了灵活和多样的用途。 目标文件是包含带有附加地址和值的助记符号的路线图。这…

PHP编写采集药品官方数据的程序

在 PHP 中编写爬虫程序&#xff0c;首先我们需要引入一些必要的库&#xff0c;如 curl 和 file_get_contents。然后&#xff0c;我们需要设置爬虫ip信息&#xff0c;以便我们可以从指定的爬虫ip服务器上获取数据。 // 引入必要的库 require_once curl.php;// 设置爬虫ip信息 $p…

招聘信息采集

首先&#xff0c;我们需要使用PHP的curl库来发送HTTP请求。以下是一个基本的示例&#xff1a; <?php // 初始化curl $ch curl_init();// 设置代理 curl_setopt($ch, CURLOPT_PROXY, "jshk.com.cn");// 设置URL curl_setopt($ch, CURLOPT_URL, "http://www…

leetcode一道比较难的链表题

今天还是继续来分享我们的链表题&#xff0c;这个题目有点难&#xff0c;主要是思路比较难想&#xff0c;但是如果沥青思路写起来就比较简单了&#xff08;我乱讲的&#xff09; 随机链表的复制 这个是题目的描述&#xff0c;大家也可以在链接里看&#xff0c;那我把这道题目…

VNC连接服务器实现远程桌面 --以AutoDL云服务器为例

VNC连接服务器实现远程桌面 --以AutoDL云服务器为例 针对本地机为Windows 云服务器租显卡跑些小模型很方便&#xff0c;但是当你想做可视化的时候&#xff0c;可能会遇到麻烦&#xff0c;云服务器没有显示输出界面&#xff0c;无法可视化一些检测任务的结果&#xff0c;或者可…

chrome 的vue3的开发者devtool不起作用

问题&#xff1a; 刚刚vue2升级到vue3&#xff0c;旧的devtool识别不了vue3数据。 原因&#xff1a; devtool版本过低。升级到最新。 解决&#xff1a; 去github下载vuetool项目代码&#xff1a; GitHub - vuejs/devtools: ⚙️ Browser devtools extension for debugging…

Dell戴尔灵越Inspiron 7700 AIO一体机电脑原厂预装Windows10系统

链接&#xff1a;https://pan.baidu.com/s/1-slgR9t4Df_eko0Y6xaeyw?pwdmk0p 提取码&#xff1a;mk0p 灵越7700一体机原装出厂系统自带声卡驱动、无线网卡驱动、面部识别等所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、MyDell等预装程序 由于时间关系,…

GEE ——errors & debuggings (2023GEE峰会总结)

简介&#xff1a; 在gee中有三种错误&#xff0c;一种就是系统错误&#xff0c;也就是我们看到的会在JavaScript code editor中出现的错误&#xff0c;也就是在程序还没有启动之前就会提示的错误&#xff0c;而客户端错误则主要是会提示一些在代码过程中的错误&#xff0c;比如…