SpringCloud实用-OpenFeign整合okHttp

文章目录

  • 前言
  • 正文
    • 一、OkHttpFeignConfiguration 的启用
      • 1.1 分析配置类
      • 1.2 得出结论,需要增加配置
      • 1.3 调试
    • 二、OkHttpFeignLoadBalancerConfiguration 的启用
      • 2.1 分析配置类
      • 2.2 得出结论
      • 2.3 测试
  • 附录
    • 附1:本系列文章链接
    • 附2:OkHttpClient 增加拦截器配置
      • 附2.1 新建配置类OkHttpConfig
      • 附2.2 调试结果

前言

众所周知,我们在使用SpringCloud OpenFeign时,默认使用的是老旧的连接器HttpURLConnection。性能以及并发量方面都差强人意。

一般而言都会对其进行优化调整。本文采用OpenFeign整合okHttp的方式替换原有的Client,去做请求。

使用java 17,spring cloud 4.0.4,springboot 3.1.4
使用项目是本系列第一篇中的项目

本文介绍两种方式的配置,一个是LoadBalancer 的,都是默认带有连接池的。

  • OkHttpFeignConfiguration
  • OkHttpFeignLoadBalancerConfiguration

正文

一、OkHttpFeignConfiguration 的启用

1.1 分析配置类

首先我们需要加入什么依赖配置呢?
依据 OkHttpFeignConfiguration 的配置内容,进行分析:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
@ConditionalOnProperty("spring.cloud.openfeign.okhttp.enabled")
protected static class OkHttpFeignConfiguration {// 类路径下有连接池时,构建连接池@Bean@ConditionalOnMissingBean(ConnectionPool.class)public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties) {int maxTotalConnections = httpClientProperties.getMaxConnections();long timeToLive = httpClientProperties.getTimeToLive();TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();return new ConnectionPool(maxTotalConnections, timeToLive, ttlUnit);}// 构建OkHttpClient实例@Beanpublic okhttp3.OkHttpClient okHttpClient(okhttp3.OkHttpClient.Builder builder, ConnectionPool connectionPool,FeignHttpClientProperties httpClientProperties) {boolean followRedirects = httpClientProperties.isFollowRedirects();int connectTimeout = httpClientProperties.getConnectionTimeout();boolean disableSslValidation = httpClientProperties.isDisableSslValidation();Duration readTimeout = httpClientProperties.getOkHttp().getReadTimeout();List<Protocol> protocols = httpClientProperties.getOkHttp().getProtocols().stream().map(Protocol::valueOf).collect(Collectors.toList());if (disableSslValidation) {disableSsl(builder);}this.okHttpClient = builder.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).followRedirects(followRedirects).readTimeout(readTimeout).connectionPool(connectionPool).protocols(protocols).build();return this.okHttpClient;}
}

1.2 得出结论,需要增加配置

从配置类中观察到,它的启用条件有2个,一个是需要引入 okhttp的包,另一个需要一行启用配置:

<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId><version>13.1</version>
</dependency>
# 启用okhttp配置
spring.cloud.openfeign.okhttp.enabled=true

1.3 调试

正常请求,在SynchronousMethodHandler.executeAndDecode(...) 中打断点,调试观察client的类型:
在这里插入图片描述

发现已经不再是之前的Default 了,换成了OkHttpClient 类型。并且,也内置了连接池以及一些基本配置信息。

二、OkHttpFeignLoadBalancerConfiguration 的启用

2.1 分析配置类

依据 OkHttpFeignLoadBalancerConfiguration 中的配置项,分析:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty("spring.cloud.openfeign.okhttp.enabled")
@ConditionalOnBean({ LoadBalancerClient.class, LoadBalancerClientFactory.class })
@EnableConfigurationProperties(LoadBalancerClientsProperties.class)
class OkHttpFeignLoadBalancerConfiguration {@Bean@ConditionalOnMissingBean@Conditional(OnRetryNotEnabledCondition.class)public Client feignClient(okhttp3.OkHttpClient okHttpClient, LoadBalancerClient loadBalancerClient,LoadBalancerClientFactory loadBalancerClientFactory,List<LoadBalancerFeignRequestTransformer> transformers) {OkHttpClient delegate = new OkHttpClient(okHttpClient);return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory,transformers);}// 省略其他配置
}

2.2 得出结论

想要让这个配置生效,需要满足OkHttpClientLoadBalancerClientOnRetryNotEnabledCondition
也就是2个依赖项,2个配置:

<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId><version>13.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId><version>4.0.4</version>
</dependency>

而配置方面需要增加:

# 启用okhttp配置
spring.cloud.openfeign.okhttp.enabled=true# 关闭负载重试
spring.cloud.loadbalancer.retry.enabled=false

2.3 测试

正常请求,在SynchronousMethodHandler.executeAndDecode(...) 中打断点,调试观察client的类型:
在这里插入图片描述
发现已经不再是之前的Default 了,换成了OkHttpClient 类型。

附录

附1:本系列文章链接

SpringCloud系列文章目录(总纲篇)

附2:OkHttpClient 增加拦截器配置

附2.1 新建配置类OkHttpConfig

增加以下拦截器配置,对请求和响应进行日志打印。

package org.feng.config;import lombok.extern.slf4j.Slf4j;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.IOException;/*** okhttp配置** @author feng*/
@Slf4j
@Configuration
public class OkHttpConfig {@Beanpublic okhttp3.OkHttpClient.Builder okHttpClientBuilder() {return new okhttp3.OkHttpClient.Builder().addInterceptor(new LoggingInterceptor());}/*** okhttp3 请求日志拦截器*/static class LoggingInterceptor implements Interceptor {@NotNull@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();long start = System.nanoTime();log.info(String.format("Sending request %s on %s%n%s",request.url(), chain.connection(), request.headers()));Response response = chain.proceed(request);long end = System.nanoTime();log.info(String.format("Received response for %s in %.1fms%n%s",response.request().url(), (end - start) / 1e6d, response.headers()));return response;}}
}

附2.2 调试结果

可以观察到日志中,打印出来了请求路径、请求头等信息。

2023-11-24T16:48:56.358+08:00  INFO 35987 --- [nio-8080-exec-1] org.feng.config.OkHttpConfig             : Sending request http://localhost:10080/hello/post on null
Content-Length: 100
Accept: */*2023-11-24T16:48:56.713+08:00  INFO 35987 --- [nio-8080-exec-1] org.feng.config.OkHttpConfig             : Received response for http://localhost:10080/hello/post in 347.4ms
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 24 Nov 2023 08:48:56 GMT
Keep-Alive: timeout=60
Connection: keep-alive

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

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

相关文章

10.打印楼梯图案和笑脸【2023.11.25】

1.问题描述 打印楼梯图案和笑脸 2.解决思路 3.代码实现 #include<stdio.h> int main(){printf("11\n");for(int i0;i<10;i){for(int j0;j<i;j){printf("FF"); }printf("\n");} return 0; }4.运行结果

《微信小程序开发从入门到实战》学习二十九

3.4 开发参与投票页面 3.4.4 使用label组件扩大单击区域 radio组件的单击区域很小&#xff0c;只有文字左侧的圆圈可以点击&#xff0c;实际使用者一般会期望点击文字也可以选中选项&#xff0c;用label组件包含radio组件&#xff0c;就可以实现点击文字也可以选项。 label组…

MySQL 基于成本的优化

其实在MySQL中⼀条查询语句的执⾏成本是由下边这两个⽅⾯组成的&#xff1a; I/O成本 我们的表经常使⽤的MyISAM、InnoDB存储引擎都是将数据和索引都存储到磁盘上的&#xff0c;当我们想查询表中的记录时&#xff0c;需要先把数据或者索引加载到内存中 然后再操作。这个从磁盘…

Linux的基本指令(二)

目录 前言 学前补充 touch指令 mkdir指令 rmdir指令 rm指令 通配符* man指令 cp指令 mv指令(重要) 补充内容&#xff1a; 1、如何快速在Linux中写出代码 2、如何看待如此多的Linux指令 cat指令 前言 关于Linux的基本指令我们会分三到四篇文章进行分析&#xff0c…

RESTful

RestFul API 何为 API&#xff1f; API&#xff08;Application Programming Interface&#xff09; 翻译过来是应用程序编程接口的意思。 我们在进行后端开发的时候&#xff0c;主要的工作就是为前端或者其他后端服务提供 API 比如查询用户数据的 API 。 但是&#xff0c; …

SD卡选型参考

文档版本日期类型REV1.02023.11.25新建 SD卡对于大家来说&#xff0c;应该很熟悉了&#xff0c;都是我们在各类电子设备中经常使用的。不过大家在购买SD卡的时候都会关注哪些参数呢&#xff1f;可能大部分使用者&#xff0c;甚至包括我在内也只是会关注下容量&#xff0c;当然是…

某瓜数据app Sign

文章目录 声明目标加密参数定位算法还原声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请私信我立即删除! 目标 之前也有写过pc端的飞瓜数据解密:JS逆向系列之某瓜数据解密 这次看一下某瓜数据app的达…

PIL.UnidentifiedImageError: cannot identify image file ...

按照网上搜的重新安装pillow库&#xff0c;对我这个不适用。我的解决方法是把有问题的图片删掉。

【后端卷前端】

为啥现在对后端要求这么高?为啥不要求前端会后端呢? 可能是后端人太多了,要求后端需要会前端的框架(vue react angular ), 这不我为了适应市场的需求来系统的学习vue了: 生成一个基础的vue项目 创建vue项目 vue create projectname 创建vitevue npm init vitelatest p…

element ui 上传组件实现手动上传

首先需要给上传组件增加http-request属性&#xff0c;这个方法中可以获取到文件&#xff0c;并按照自己的方式进行上传。 <el-uploadreffileUploadaction#:http-requesthttpRequest:on-preview"handlePreview":on-remove"handleRemove":limit"1&q…

科研/比赛必备工具及系列笔记集合

科研/比赛必备工具及系列笔记集合 零、前言一、常用工具系列1.1 笔记平台使用感受系列1.2 常用开发平台系列 二、论文系列2.1 检索工具系列2.2 投稿调研系列2.3 常见国际期刊/会议2.4 常见中文核心期刊/会议 三、文献系列3.1 画图工具系列3.2 翻译工具系列3.3 英文纠正系列3.4 …

手摸手Element-ui组件化开发

前端环境准备 编码工具: VSCode 依赖管理:NPM 项目构建: Vuecli NPM的全称是Node Package Manager&#xff0c;是一个NodeJS包管理和分发工具&#xff0c;已经成为了非官方的发布Node模块&#xff08;包&#xff09;的标准。2020年3月17日&#xff0c;Github宣布收购npm&am…

「Verilog学习笔记」数据累加输出

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 在data_out准备好&#xff0c;valid_b拉高时&#xff0c;如果下游的ready_b为低&#xff0c;表示下游此时不能接收本模块的数据&#xff0c;那么&#xff0c;将会拉低ready…

ImportError: No module named python_util.util

ImportError: No module named python_util.util 从师兄那里拷贝了一个python文件&#xff0c;运行报错ImportError: No module named python_util.util&#xff0c;python小白上网搜&#xff0c;并没有搜到有价值的答案。。。经过摸索&#xff0c;最后解决。 其实这就是缺少…

肾合胶囊 | 修行人追求的“长生不老”,其实就是一个“增阳消阴”的过程!

关于生命的问题&#xff0c;在人们面前有两条路任你选择。 人的生命活动靠精气来维持&#xff0c;善于保养精气者长生&#xff0c;否则就是短寿。 长生或短寿&#xff0c;只能由你自己选择。 其实要想长生并不是很难的事情&#xff0c;长生药就在你自己身上&#xff0c;只不…

Exchange意外登录日志

最近在审计Exchange邮件系统的时候&#xff0c;发现大量用户半夜登录的日志。而且都是成功的&#xff0c;几乎没有失败的情况。其中Logon Type 8表示用户从网络登录。 Logon type 8: NetworkCleartext. A user logged on to this computer from the network. The user’s pas…

HCIA-RS基础-RIP路由协议

前言&#xff1a; RIP路由协议是一种常用的距离矢量路由协议&#xff0c;广泛应用于小规模网络中。本文将详细介绍RIP路由协议的两个版本&#xff1a;RIPv1和RIPv2&#xff0c;并介绍RIP的常用配置命令。通过学习本文&#xff0c;您将能够掌握RIP协议的基本原理、RIPv1和RIPv2的…

MIPI 打怪升级之DSI篇

MIPI 打怪升级之DSI篇 目录 1 Overview2 DSI Mode 2.1 Video 模式2.2 Command 模式3 DSI Physical Layer 3.1 数据流控3.2 双向性3.3 Video Mode Interfaces3.4 Command Mode Interfaces3.5 Clock4 多通道管理 4.1 通道数匹配4.2 线上数据分布5 DSI 协议 5.1 包格式 5.1.1 短包…

秋招如何准备?有什么建议?

秋招&#xff0c;是毕业生最好的求职渠道&#xff0c;没有之一。尽管还有春招&#xff0c;社招......都不如秋招重要&#xff0c;因为秋招的机会更多..... 如何准备秋招&#xff1f; 1、简历很重要 一个好的简历&#xff0c;就是敲门砖&#xff0c;这是你跟企业HR的第一次亲…

什么是测试系统工程师(TSE)

TSE(TestSystemEngineer)简称测试系统工程师,作为系统工程&#xff08;SE&#xff09;团队的一员&#xff0c;很多公司目前还没有这样的角色&#xff0c;导致测试部分往往处理弱势&#xff0c;第一&#xff0c;不能进行端到端开发流程的测试&#xff0c;第二,不能对产品最终的测…