1. 什么是 okhttp ?

okhttp 是由 square 公司开源的一个 http 客户端。在 Java 平台上,Java 标准库提供了 HttpURLConnection 类来支持 HTTP 通讯。不过 HttpURLConnection 本身的 API 不够友好,所提供的功能也有限。大部分 Java 程序都选择使用 Apache 的开源项目 HttpClient 作为 HTTP 客户端。Apache HttpClient 库的功能强大,使用率也很高。

2. 为什么要使用 okhttp ?

okhttp 的设计初衷就是简单和高效,这也是我们选择它的重要原因之一。它的优势如下:

  • 支持 HTTP/2 协议。
  • 允许连接到同一个主机地址的所有请求,提高请求效率。
  • 共享Socket,减少对服务器的请求次数。
  • 通过连接池,减少了请求延迟。
  • 缓存响应数据来减少重复的网络请求。
  • 减少了对数据流量的消耗。
  • 自动处理GZip压缩。

3. 实战目标

  • Feign 中使用 okhttp 替代 httpclient
  • Zuul 中使用 okhttp 替代 httpclient

4. 在 Feign 中使用 okhttp

首先介绍一下工程结构,本演示工程包含 provider-server、consumer-server、eureka-server 和 zuul-server 。

4.1 consumer-server 依赖 pom.xml 如下:

代码清单:chapter19/consumer-server/pom.xml


<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
</dependencies>
  • feign-okhttp 这里无需指定版本,目前引入的 feign-okhttp 版本为 10.2.3 ,而 okhttp 的版本为 3.8.1 ,如图:

4.2 配置文件 application.yml

代码清单:chapter19/consumer-server/src/main/resources/application.yml


feign:
httpclient:
enabled: false
okhttp:
enabled: true
  • 在配置文件中需关闭 feign 对 httpclient 的使用并开启 okhttp 。

4.3 配置类 OkHttpConfig.java

代码清单:chapter19/consumer-server/src/main/java/com/springcloud/consumerserver/config/OkHttpConfig.java


@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class OkHttpConfig { @Bean
public OkHttpClient okHttpClient(){
return new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.connectionPool(new ConnectionPool(10 , 5L, TimeUnit.MINUTES))
.addInterceptor(new OkHttpLogInterceptor())
.build();
}
}
  • 在配置类中将 OkHttpClient 注入 Spring 的容器中,这里我们指定了连接池的大小,最大保持连接数为 10 ,并且在 5 分钟不活动之后被清除。
  • 笔者这里配置了一个 okhttp 的日志拦截器。

4.4 日志拦截器 OkHttpLogInterceptor.java

代码清单:


@Slf4j
public class OkHttpLogInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
log.info("OkHttpUrl : " + chain.request().url());
return chain.proceed(chain.request());
}
}
  • 这里实现的接口是 okhttp3.Interceptor ,并不是 Spring Boot 中的 Interceptor。
  • 笔者这里仅简单打印了 okhttp 请求的路径,如果有业务校验权限等需求可以放在拦截器中实现。

远程 Feign 调用代码略过,有需要的读者可以访问 Github 仓库获取。

5. 在 Zuul 中使用 okhttp

5.1 pom.xml 加入 okhttp 依赖

代码清单:chapter19/zuul-server/pom.xml


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

5.2 配置文件开启 okhttp

代码清单:chapter19/zuul-server/src/main/resources/application.yml


ribbon:
http:
client:
enabled: false
okhttp:
enabled: true
  • 因为 Zuul 的负载均衡实现是通过 Ribbon 实现的,所以 Http 客户端的配置自然也是对 Ribbon 组件的配置。

6. 测试

我们修改 idea 启动配置,分别在 8000 和 8001 端口启动 provider-server ,并且顺次启动其余工程,打开浏览器访问链接:http://localhost:8080/consumer/hello ,多次刷新,可以看到 Hello Spring Cloud! Port : 8000Hello Spring Cloud! Port : 8001 交替书出现,可以证明负载均衡已经成功,可以查看 consumer-server 的日志,如下:

2019-09-23 23:15:27.097  INFO 10536 --- [nio-9000-exec-5] c.s.c.intercepter.OkHttpLogInterceptor   : OkHttpUrl : http://host.docker.internal:8001/hello
2019-09-23 23:15:27.593 INFO 10536 --- [nio-9000-exec-6] c.s.c.intercepter.OkHttpLogInterceptor : OkHttpUrl : http://host.docker.internal:8000/hello
2019-09-23 23:15:27.942 INFO 10536 --- [nio-9000-exec-7] c.s.c.intercepter.OkHttpLogInterceptor : OkHttpUrl : http://host.docker.internal:8001/hello
2019-09-23 23:15:28.251 INFO 10536 --- [nio-9000-exec-9] c.s.c.intercepter.OkHttpLogInterceptor : OkHttpUrl : http://host.docker.internal:8000/hello
2019-09-23 23:15:47.877 INFO 10536 --- [nio-9000-exec-8] c.s.c.intercepter.OkHttpLogInterceptor : OkHttpUrl : http://host.docker.internal:8001/hello

可以看到我们刚才自定义的日志正常打印,证明现在访问确实是通过 okhttp 来进行访问的。

7. 示例代码

示例代码-Github

示例代码-Gitee

跟我学SpringCloud | 第二十章:Spring Cloud 之 okhttp的更多相关文章

  1. 跟我学SpringCloud | 第二篇:注册中心Eureka

    Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry和Service Discovery实现.也是springcloud体系中最重要最核心的组 ...

  2. springcloud(一):Spring Cloud

    研究了一段时间Spring Boot了准备向Spring Cloud进发,公司架构和项目也全面拥抱了Spring Cloud.在使用了一段时间后发现Spring Cloud从技术架构上降低了对大型系统 ...

  3. springCloud学习6(Spring Cloud Sleuth 分布式跟踪)

    springcloud 总集:https://www.tapme.top/blog/detail/2019-02-28-11-33 前言   在第四篇和第五篇中提到一个叫关联 id的东西,用这个东西来 ...

  4. springcloud学习04- 断路器Spring Cloud Netflix Hystrix

    依赖上个博客:https://www.cnblogs.com/wang-liang-blogs/p/12072423.html 1.断路器存在的原因 引用博客 https://blog.csdn.ne ...

  5. springcloud(五):Spring Cloud 配置中心的基本用法

    Spring Cloud 配置中心的基本用法 1. 概述 本文介绍了Spring Cloud的配置中心,介绍配置中心的如何配置服务端及配置参数,也介绍客户端如何和配置中心交互和配置参数说明. 配置中心 ...

  6. springcloud(六):Spring Cloud 配置中心采用数据库存储配置内容

    Spring Cloud 配置中心采用数据库存储配置内容 转自:Spring Cloud Config采用数据库存储配置内容[Edgware+] Spring Cloud Server配置中心采用了G ...

  7. Spring Cloud Alibaba (一): SpringCloud与SpringBoot版本选型

    前言   近年SpringCloud与SpringBoot更新迭代非常频繁,导致我们对两者的版本选型非常的困难.若是版本选择有问题, 会导致开发中调试兼容性占用非常多的得必要时间. SpringClo ...

  8. 跟我学SpringCloud | 第三篇:服务的提供与Feign调用

    跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简 ...

  9. 跟我学SpringCloud | 终篇:文章汇总(持续更新)

    SpringCloud系列教程 | 终篇:文章汇总(持续更新) 我为什么这些文章?一是巩固自己的知识,二是希望有更加开放和与人分享的心态,三是接受各位大神的批评指教,有任何问题可以联系我: inwsy ...

随机推荐

  1. .net测试篇之测试神器Autofixture在几个复杂场景下的使用示例以及与Moq结合

    系列目录 为String指定一个值. 在第三节里我们讲了如何使用自定义配置加上一个自定义算法生成一个自定义字符串,然而有些时候我们仅仅是需要某个字段是有意义的,这个时候随便生成的字符串也满足不了我们的 ...

  2. ​综述 | SLAM回环检测方法

    本文作者任旭倩,公众号:计算机视觉life成员,由于格式原因,公式显示可能出问题,建议阅读原文链接:综述 | SLAM回环检测方法 在视觉SLAM问题中,位姿的估计往往是一个递推的过程,即由上一帧位姿 ...

  3. cookies和sessionstorage和localstorage区别

    相同点:客户端都会存储 不同点 不同点 存储大小 有效时间 数据与服务器交互方式 cookies <=4K 在设置cookie过期之前一直有效(无论窗口浏览器是否关闭) 正常情况下,cookie ...

  4. 解决ionic 启动页面图片没有显示及启动页出现黑白屏

    1.ionic 正确打包完app, 并且按照正常的步骤配置config.xml文件之后 ,启动页面还是不能正常的显示出来,而是黑了一下之后,就进入首页了 原因很有可能就是你没有装cordova-plu ...

  5. Codeforces 936C

    题意略. 思路: 这个题目没做出来是因为缺少一个整体的构造思路. 正确的构造思路是不断地在s中去构造并且扩大t的后缀,构造好的后缀总是放在前面,然后不断地把它往后挤,最后将s构造成t. 比如: 现在在 ...

  6. Codeforces 976F

    题意略. 思路:为了保证每个点都有至少k条边覆盖,我们可以让二分图的左半边与源点s相连,连容量为indegree[i] - k的边(如果正着想不好想,我们可以想它的反面, 限制它反面的上限,从而保证我 ...

  7. C 扩展对闭包特性的支持

    今日听说某君批评 C 语言说它[输入一个参数返回一个函数]很困难. 例如在 Python 中,你可以 def addn(n): def addx(x): return n + x return add ...

  8. HDU 6394 Tree 分块 || lct

    Tree 题意: 给你一颗树, 每一个节点都有一个权值, 如果一个石头落在某个节点上, 他就会往上跳这个的点的权值步. 现在有2种操作, 1 把一个石头放在 x 的位置 询问有跳几次才跳出这棵树, 2 ...

  9. HDU-6437 Videos

    HDU-6437 题意:一天有n个小时,现在有m场电影,每场电影有一个愉悦值,有k个人,电影分2种类型A, B, 并且每一场电影只能一个人看, 一个人可以看无数次电影, 只要时间足够, 但是连续看同一 ...

  10. CodeForces 223C Partial Sums 多次前缀和

    Partial Sums 题解: 一个数列多次前缀和之后, 对于第i个数来说他的答案就是 ; i <= n; ++i){ ; j <= i; ++j){ b[i] = (b[i] + 1l ...