百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

SpringCloud OpenFeign 使用 okhttp 发送 HTTP 请求与 HTTP/2 探索

suiw9 2024-10-29 16:41 167 浏览 0 评论

背景

SpringCloud OpenFeign 支持3种 HTTP client 来发送请求,分别是:

  • HttpURLConnection 默认形式,Java提供。
  • Apache HttpClient 5
  • okhttp

我们使用的 HttpURLConnection 即默认形式,预期提升请求时效,结合推荐,替换成 okhttp 测试效果。

okhttp 介绍

okhttp 有如下特性优势:

  • 支持 HTTP/2
  • 使用 HTTP 连接池 (HTTP/2 不可用)
  • 使用GZIP 压缩
  • 对响应缓存
  • 连接恢复,如果访问的服务有多个地址,那么连接一个地址失败后,重试其他地址

我们可使用到的特性是 HTTP 连接池和连接恢复。

实现

代码设置

1.在 pom.xml 文件中引入 okhttp 的包。

<dependency>
		<groupId>io.github.openfeign</groupId>
		<artifactId>feign-okhttp</artifactId>
	</dependency>

2.在 Spring 的配置文件中,设置开启 okhttp

feign:
  okhttp:
    enabled: true

测试验证

调试 Feign 请求的代码,可以看到请求发送已经使用了 okhttp。

性能比较

对一个请求,其中实现中包含对另一个服务接口的 Feign 调用,进行 ab 压测,使用100个并发,发送10000次请求,比较其耗时。

1. HttpURLConnection 耗时情况

2. okhttp 耗时情况

可以看到请求时效的提升。

遇到的问题

1. method GET must not have a request body

Caused by: java.lang.IllegalArgumentException: method GET must not have a request body.
	at okhttp3.Request$Builder.method(Request.kt:258)

是因为 okhttp 框架要求 GET 请求不能有 requestbody 。当方法设置 `@RequestMapping` 而未设置 method 时,使用 GET 请求。

修改方案:1. POST 方法时,在 @RequestMapping 上设置 method 参数。2. GET 方法时,参数使用 @RequestParam 而不是 @RequestBody。

okhttp 关于 GET 请求是否支持 requestbody ,可在 github issue 区查看讨论。

2. jar 包版本冲突报错

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [okhttp3.OkHttpClient$Builder]: Factory method 'okHttpClientBuilder' threw exception; nested exception is java.lang.NoSuchFieldError: Companion
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
	... 111 common frames omitted
Caused by: java.lang.NoSuchFieldError: Companion
	at okhttp3.internal.Util.<clinit>(Util.kt:70)
	at okhttp3.internal.concurrent.TaskRunner.<clinit>(TaskRunner.kt:309)
	at okhttp3.ConnectionPool.<init>(ConnectionPool.kt:41)
	at okhttp3.ConnectionPool.<init>(ConnectionPool.kt:47)

是因为有其他 jar 包引入了 okhttp ,版本不同,底层实现的方法有不同。通过 IDE 查看各依赖。

修改方案:因为其他 jar 包引入的 okhttp 版本较低,升级高版本不可用。该服务采用不开启 okhttp,修改服务的 pom 文件不引入 okhttp 包。因为我们是基础的通用依赖,使用 exclusion 排除。

<exclusions>
	<exclusion>
		<groupId>io.github.openfeign</groupId>
		<artifactId>feign-okhttp</artifactId>
	</exclusion>
</exclusions>

Feign 请求开启 HTTP/2 探索

okhttp 支持 HTTP/2,那么我们使用 HTTP/2 有什么好处呢?在 HTTP/2 中,当客户端请求数据时,服务器会一次性将多个数据流发送到客户端,而不是逐个依次发送,这种数据传输方法成为多路复用。同一个主机的所有请求共用一个 socket 连接。

HTTP/2 的类型

1.h2 (HTTP/2 over TLS)

2.h2c (HTTP/2 over TCP)

h2 必须要开启 SSL,也就是基于 HTTPS。而 h2c 可以不开启 SSL。

server 端开启 HTTP/2

Spring 对 h2 和 h2c 都支持。开启 HTTP/2 通过配置文件开关即可。添加如下配置:

server:
  http2:
    enabled: true

服务启动后,发送请求查看到,验证服务端开启了 HTTP/2 。

`curl -I --http2 localhost:8885/***`



Feign请求的客户端开启 HTTP/2

1.okhttp 支持 HTTP/2,但是只支持 h2 的形式。目前我们项目并未引入 SSL,所以不可行。框架也无支持 h2c 的计划,相关讨论在github issue 区。

2.HttpURLConnection 在 HTTP/2 协议全面改动后,这个类无法升级支持。Java 是提供了一套新的类来支持 HTTP/2,它们是 HttpClient。而 OpenFeign 的接入还在 snapshot 版本,SpringCloud 接入还需要等待。

GitHub github = Feign.builder()
                     .client(new Http2Client())
                     .target(GitHub.class, "https://api.github.com");


<parent>
    <groupId>io.github.openfeign</groupId>
    <artifactId>parent</artifactId>
    <version>12.2-SNAPSHOT</version>
  </parent>

3.Apache HttpClient 5 启用该 http client 后,打开 Spring 的 HTTP/2 开关,发起请求并不是 HTTP/2 的形式,h2c 形式未成功。

如上 SpringCloud OpenFeign 开启 HTTP/2 均未成功,打算等 OpenFeign 12.2发布后再测试。

相关推荐

Apicloud功能模块使用customToast

[toast](#a1)概述customToast弹出一个定时自动关闭的提示框,自定义Toast,自定义提示框颜色、透明度、字体大小、字体颜色、圆角幅度,显示时间;让Toast更完美的融入应用,不...

wxPython - 在程序中使用拖放(wxpython设置滚动条)

实战wxPython系列-052在GUI程序中,拖放是单击虚拟对象并将其拖到不同位置或另一个虚拟对象上的操作(或对该操作的支持)。一般来说,它可用于调用多种类型的操作,或在两个抽象对象之间创建各种类型...

美化Python GUI界面!让你的窗口拥有Win11般的质感 | pywinstyles

1.PythonGUI外观个性化的福音在使用Python开发GUI时,我们经常会使用如Tkinter、PyQt等常见的库,然而这些库的默认界面总显得有些...普通。而如果你想让你的PythonG...

5月BestBuy(5月英文)

Intel处理器排行榜No.1Intel酷睿i511600KF1799元No.2Intel酷睿i511400F1249元No.3Intel酷睿i711700K2899元酷睿i511...

手把手教您使用Python+Flutter开发在线教育系统(上),纯干货!

一、系统架构设计...

Python开发GUI运维工具具体案列(python运维开发做什么)

在Python开发GUI运维工具的具体实践中,不同GUI库的案例各有特色,以下是结合运维场景的典型实现案例及技术方案:一、基础运维工具案例...

开发图形界面Tkinter、wxPython、PyQt、PySide选哪一个?

  学习Python,就不得不提一下Python的图形界面开发,如果只用命令行写程序,用户体验不太好,难以胜任复杂的人机交互场景。Python的图形界面开发库常用的有:Tkinter、wxPython...

wxPython和PyQt谁才是最赞的Python GUI库

Python是一种解释型、面向对象、动态数据类型的高级程序设计语言,PythonGUI图形库允许Python程序员很方便的创建完整的、功能键全的GUI用户界面。作为Python开发者,你迟早都会用到...

wxpython入门第五步(组件)(wxpython怎么用)

Widgets在本节中,我们将介绍wxPython中的基本widgets。每个组件都会有一个小的代码示例。wxPython中有很多不同的组件,包括按钮、复选框、滑块和列表框。wx.Buttonwx....

wxpython简介(python的wxpython)

PythonPython是一种成功的脚本语言,它最初是由GuidovanRossum开发的。它于1991年首次发布。Python的灵感来自于ABC和Haskell编程语言。Python是一种高级...

所见即所得,跨平台快速GUI界面RAD设计

Linux一路走来,界面组件很多,TK、gtk、Qt、wxWidget等。Tk古老而又厚重,不失motif风格,gtk+glade别具特色,Qt轻快时尚,许多语言本身没有gui可用,于是做接口加wra...

Spring Security权限控制系列(二)

环境:Springboot2.4.12+SpringSecurity5.4.9本篇主要内容:请求拦截及自定义登录页面上一篇:《...

Spring整合CXF 发布webservice接口服务器和客户端,WSDL简单解析

在垮平台通讯中有很多的接口方式,这里做个简单的webservice接口。发布webservice接口的方式也多种多样,这里做个基于CXF的webservice接口。首先做点知识储备,javax.jws...

聊聊如何对eureka管理界面进行定制化改造

前言在nacos还未面世之前,eureka基本上就是springcloud全家桶体系注册中心的首选,随着nacos的横空出世,越来越多基于springcloud的微服务项目采用nacos作为注册中心,...

Spring Boot 四大核心组件,你知道几个?

前言...

取消回复欢迎 发表评论: