要使用OkHttp,一定要知道它的透明压缩,否则死都不知道怎么死的;或者活也不知道为什么活的不舒坦。

反正不是好事。

什么叫透明压缩呢?OkHttp在发送请求的时候,会自动加入gzip请求头Accept-Encoding:gzip。所以,当返回的数据带有gzip响应头时Content-Encoding=gzip,OkHttp会自动帮我们解压数据。(Accept-EncodingContent-Encoding是一对请求头,分别对应着请求和返回)

为什么要进行压缩呢?因为它能大幅减少传输的容量。像一些CPU资源占用不高的服务,比如Kafka,我们就可以开启gzip压缩,加快信息的流转。

这个压缩比有多高呢?可以看下下面实实在在的截图,对于普通的xml或者json,数据可以由9MB压缩到350KB左右,压缩比足足达到了26

它让系统性能飞起来

SpringCloud微服务体系,现在有非常多的公司在用。即使是一些传统企业,一些大数据量的toB企业,也想尝一尝螃蟹。

对于一个简单的SpringBoot服务,我们只需要在yml文件中配置上相应的压缩就可以了。这样,我们就打通了浏览器到Web服务的这一环。这种压缩方式,对于大数据量的服务来说,是救命式的!

具体配置如下。

server:port: 8082compression:enabled: truemin-response-size: 1024mime-types: ["text/html","text/xml","application/xml","application/json","application/octet-stream"]

它所对应的Spring配置类是org.springframework.boot.web.server.Compression

但是不要高兴太早。由于是分布式环境,这里面调用链就会长一些。即使是在内网,动辄十几MB的网络传输,也会耗费可观的时间。

如上图,一个请求从浏览器到达真正的服务节点,可能要经过很多环节。

  • nginx转发请求到微服务网关zuul

  • zuul转发到具体的微服务A

  • 微服务A通过Feign接口调用微服务B

如果我们的数据,大多数是由微服务B提供的,那么上面的任何一个环节传输效率慢,都会影响请求的性能。

所以,我们需要开启Feign接口的gzip压缩。使用OkHttp的透明代理是最简单的方式。

首先,在项目中引入feign的jar包。

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

其次,在yml文件中启用OkHttp作为feign的客户端请求工具包。稳妥起见,我们同时屏蔽了httpclient,这个东西太重太老了。

feign:httpclient:enabled: falseokhttp:enabled: true

到此为止,我们就可以享受OkHttp的透明代理带来的便捷性了。

假如你的应用数据包大,调用链长,这种方式甚至会给你的服务带来数秒的性能提升。xjjdog就曾经靠调整几个参数,就让一个蜗牛系统飞了起来。大家惊呼:原来B端也可以C一下。

OkHttp是如何实现透明压缩的?

OkHttp对于透明压缩的处理,是通过拦截器来做的。具体的类,就是okhttp3.internal.http.BridgeInterceptor

具体代码如下,当判断没有Accept-Encoding头的时候,就自行加入一个。

// If we add an "Accept-Encoding: gzip" header field we're responsible for also decompressing
// the transfer stream.
boolean transparentGzip = false;
if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) {transparentGzip = true;requestBuilder.header("Accept-Encoding", "gzip");
}

最关键的代码在下面。

if (transparentGzip&& "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding"))&& HttpHeaders.hasBody(networkResponse)) {GzipSource responseBody = new GzipSource(networkResponse.body().source());Headers strippedHeaders = networkResponse.headers().newBuilder().removeAll("Content-Encoding").removeAll("Content-Length").build();responseBuilder.headers(strippedHeaders);String contentType = networkResponse.header("Content-Type");responseBuilder.body(new RealResponseBody(contentType, -1L, Okio.buffer(responseBody)));
}

可以看到if语句里,有三个条件。

  • 程序没有设置Accept-Encoding,启用了透明压缩

  • 服务端有Content-Encoding头,并启用了gzip压缩

  • 有数据包

只有同时满足这三个条件,OkHttp的透明压缩才会起作用,帮我们自动解压。

它挖的坑有点深

可惜的是,上面的关键代码,只有if,没有else,也就是当其中的任何一个条件不满足,后端的数据包将原封不动的返回。

2、3两个条件是没有什么问题的,原样返回后端数据并没有什么损害,问题就出在第一个条件里。

如果你在代码中,使用了下面的代码:

Request.Builder builder = chain.request().newBuilder().addHeader("Accept", "application/json").addHeader("Accept-Encoding", "gzip");

也就是手动设置了Accept-Encoding头信息。这很常见,因为这体现了程序员思维的严谨。

正是这种严谨,造成了问题。

假如你的后端应用刚开始是没有开启gzip压缩的,这时候两者相安无事;但如果你的后端应用突然有一天开启了gzip压缩,你的这段代码将全部over。

原因就是,服务端gzip数据包会原样返回,你需要手动处理gzip数据包。

所以,不加是好事,加了反而会坏事,除非你想自己处理gzip数据。

由于OkHttpAndroid上应用也非常广泛,如果你不知道这个细节,造成的后果就是灾难性的。客户端更新慢,只能老老实实回退服务端了。

智能的背后,总有些肉眼不可见的细节。就像是xjjdog纯情的背后,总有一份羞涩。只有深入了解,你才会知道它的美。


往期推荐

JDK15正式发布,新增功能预览!

2020-09-17

漫画:什么是红黑树?(整合版)

2020-09-15

字符串操作的12个小技巧!

2020-09-10

URL 去重的 6 种方案!(附详细代码)

2020-09-09

关注下方二维码,收获更多干货!

OkHttp透明压缩,收获性能10倍,外加故障一枚相关推荐

  1. OceanBase 3.2.3 发版|HTAP引擎全面升级,TPC-H性能10倍提升~

    作为企业级原生分布式数据库,OceanBase 自创立以来一直坚持原生分布式的发展路线,其高兼容.金融级容灾和高可用.透明扩展.稳定安全等能力已经在金融.政府.运营商.互联网等各个行业得到了充分验证以 ...

  2. vue2.0_实现图片上传前进行压缩(约10倍)

    前言 1.以VantUI组件库中van-uploader文件上传为例 2.本例以图片大于2M才开始压缩,压缩条件可自行调节 3.压缩完成得到图片的base64格式,可转换成file文件 4.读取到图片 ...

  3. 联想造超级计算机,联想将造超级计算机 性能10倍于IBM蓝色基因

    作者:刘彦青 [赛迪网讯]7月29日消息,联想集团的一名发言人于当地时间本周四证实说,联想集团已经启动一个研究项目,开发性能近10倍于当前世界上最快的超级计算机的超级计算机系统. 联想集团在北京的女发 ...

  4. 137% YOLOv3加速、10倍搜索性能提升!百度飞桨推出模型压缩神器

    深度学习模型压缩,又有利器问世. 最新消息,历经一年四个版本打磨之后,百度推出最新深度学习模型压缩工具PaddleSlim1.0. 不仅囊括了深度学习模型压缩中常用的量化.剪裁.蒸馏.模型结构搜索.模 ...

  5. 如何让你的Nginx 提升10倍性能?

    来源:www.zcfy.cc/article/10-tips-for-10x-application-performance-nginx-22.html 原文:https://www.nginx.co ...

  6. 实现分区表性能提升超 10 倍,解密 TDSQL PG 版开源升级特性

    1 月 11 日,腾讯云 TDSQL PG 开源版(开源代号 TBase)再升级:分布区表关联查询性能(join)提升超 10 倍,同时提升了产品在分布式场景下的易用性,增加灵活可用的功能组件. 该升 ...

  7. 137% YOLOv3加速、10倍搜索性能提升!这样的惊喜,最新版PaddleSlim有10个

    允中 发自 凹非寺  量子位 编辑 | 公众号 QbitAI 深度学习模型压缩,又有利器问世. 最新消息,历经一年四个版本打磨之后,百度推出最新深度学习模型压缩工具PaddleSlim1.0. 不仅囊 ...

  8. 面试官:我想用Nginx提升系统10倍性能,你有哪些建议?

    提升Web应用的性能从未像今天这样刻不容缓. 在线经济活动的比例日益提高,就连发展中国家和地区的经济活动都已经有5%以上在线进行了(相关数据请参考本文后面的资源).在这个超级链接.随时在线的现代世界, ...

  9. 如何将 Nginx 性能提升10倍?这10个“套路”请收好!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 提升 ...

最新文章

  1. 为何Google将几十亿行源代码放在一个仓库?| CSDN博文精选
  2. h5MYSQL并进行增删查改_mysql增删改查
  3. 树莓派_FTP服务器的搭建
  4. go iris 连接 mysql 异步_go语言解决并发的方法有哪些?
  5. [Shell]条件判断与流程控制:if, case, for, while, until
  6. 《SpringMVC从入门到放肆》一、概述
  7. 设计模式实践系列 (3) - 装饰模式 ( Decorator )
  8. 周鸿祎:网络安全面前 没有国家可以袖手旁观
  9. java tar压缩工具类_分享apache的commons-compress的TarUtils压缩工具类对文件数据进行加解密、解析及格式化校验等操作...
  10. 数据结构与算法 - 图论
  11. Win10 企业版 2016 长期服务版激活
  12. 五年级计算机课主要学哪些内容,五年级下册信息技术课程纲要
  13. 如何使用阿里云创建镜像和实例
  14. VSCode通过源代码管理插件GitLens提交项目代码的过程
  15. input输入框去除历史记录
  16. base64 decode java_Java实现Base64编解码
  17. Xshell连接ubuntu后vi编辑器中数字小键盘乱码
  18. 《深入理解Java虚拟机》-周志明(转)
  19. Android OTA 问题分析
  20. kubernetes 安装 Dashboard

热门文章

  1. 三万字速通SSM框架入门知识点,快速上手CRUD
  2. weblogic忘记console密码
  3. 4-什么是Image和container
  4. 获取数据库名称dbName
  5. 迟到的年度总结,我们应该收放自如
  6. centos6设置静态IP
  7. Django 缓存系统
  8. linuxSAMBA共享
  9. 控件UI性能调优 -- SizeChanged不是万能的
  10. 2进制、8进制、10进制、16进制...各种进制间的轻松转换(c#)