前言:
现在我们对“java启动服务后http怎么调用”可能比较看重,同学们都需要剖析一些“java启动服务后http怎么调用”的相关内容。那么小编同时在网上网罗了一些关于“java启动服务后http怎么调用””的相关资讯,希望我们能喜欢,各位老铁们快快来了解一下吧!背景
SpringCloud OpenFeign 支持3种 HTTP client 来发送请求,分别是:
HttpURLConnection 默认形式,Java提供。Apache HttpClient 5okhttp
我们使用的 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 omittedCaused 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, ";);
<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发布后再测试。
标签: #java启动服务后http怎么调用