May 31, 2021 Article blog
The article comes from the public number: little sister taste, the author's little sister dog
To use
OkHttp
be sure to know its
透明压缩
otherwise you don't know how to die, or you don't know why you live.
It's not a good thing anyway.
What do you mean
透明压缩
ttps
automatically adds the gzip request header
Accept-Encoding:gzip
when the request is sent. S
o, when the returned data comes with a gzip response
Content-Encoding=gzip
OkHttps
automatically unzip the data.
Accept-Encoding
and
Content-Encoding
are a pair of request heads that correspond to requests and returns, respectively)
Why compression? B ecause it can significantly reduce the capacity of the transfer. Like some cpu-intensive services, such as Kafka, we can turn on gzip compression and speed up the flow of information.
How high is this compression ratio?
You can see the real screenshot below, for a normal
xml
or
json
the data can be compressed from
9MB
to
350KB
the compression ratio is enough to
26
SpringCloud
microservices, there are now a lot of companies working.
Even some traditional businesses, some big data
toB
companies, want to try crabs.
For a simple SpringBoot service, we just need to configure the corresponding compression in the yml file. I n this way, we get through this part of the browser to the Web service. This compression method, for the big data volume of services, is life-saving!
The configuration is as follows.
server:
port: 8082
compression:
enabled: true
min-response-size: 1024
mime-types: ["text/html","text/xml","application/xml","application/json","application/octet-stream"]
The Spring configuration class it corresponds to is
org.springframework.boot.web.server.Compression
But don't be happy too early. B ecause it's a distributed environment, the call chain is longer. Even on the intranet, moving a dozen MB of network transmission can take considerable time.
As shown above, a request to reach a real service node from the browser can go through many processes.
If most of our data is provided by microservices B, any of these links are transmitted slowly, affecting the performance of the request.
So we need to turn on gzip compression for the Feign interface. Using a transparent proxy for OkHttps is the easiest way.
First, introduce feign's jar package into the project.
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
Second, enable OkHttps in the yml file as a client request kit for feign. To be sure, we blocked httpclient at the same time, which is too heavy and too old.
feign:
httpclient:
enabled: false
okhttp:
enabled: true
At this point, we can enjoy the convenience of OkHttps' transparent proxy.
If your app packets are large and the call chain is long, this approach can even give your service a performance boost
数秒
x
jjdog used to let a snail system fly by adjusting a few parameters.
Everyone exclaimed: the original B side can also C a.
OkHttps handles
transparent compression with interceptors.
The specific class is
okhttp3.internal.http.BridgeInterceptor
The code is as follows, and when you decide that there is no
Accept-Encoding
add one yourself.
// 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");
}
The most critical code is below.
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)));
}
You can see that there are three conditions in the
if
statement.
Accept-Encoding
set up and transparent compression is enabled
Content-Encoding
header and gzip compression is enabled
Only if these three conditions are met at the same time will the transparent compression of OkHttps work, helping us to unzip automatically.
Unfortunately, the above key code, only
if
no
else
that is, when any of these conditions are not met, the back-end packets will be returned intact.
2, 3 two conditions is no problem, as is to return back-end data and no damage, the problem is in the first condition.
If you're in code, use the following code:
Request.Builder builder = chain.request()
.newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Accept-Encoding", "gzip");
That is,
Accept-Encoding
information is set manually.
This is common because it reflects the rigour of the programmer's mind.
It is this rigour that is causing the problem.
If your back-end app doesn't turn on
gzip
compression at first, it's okay, but if your back-end app suddenly turns on
gzip
compression one day, your code will be all over.
The reason is that the service-side gzip packet returns as is, and you need to manually process the gzip packet.
So, if you don't add it, it's a bad thing to add it, unless you want to handle the gzip data yourself.
Because
OkHttp
is also widely used on
Android
if you don't know this detail, the consequences can be disastrous.
Client updates are slow and can only be honestly rolled back to the service side.
Behind the intelligence, there are always details that are invisible to the naked eye. I t's like behind xjjdog's pure feelings, there's always a shyness. Only if you know more will you know its beauty.
Above is
W3Cschool编程狮
about
OkHttp transparent compression, harvest performance 10 times, plus a fault of a
related introduction, I hope to help you.