Concept
HTTP short connections (non-persistent connections) means that the connection is closed after the client and the server have made an HTTP request/response. Therefore, the next HTTP request/Response operation requires a re-establishment of the connection.
An HTTP long connection (persistent connection) means that after a connection is established between the client and the server, multiple request/response operations can be made on the connection. Persistent connections can either set the expiration time or not set.
Why didn't I say http/1.0? Default short connection, http/1.1 up, default long connection. Because the first time I read this statement, I thought I understood, actually did not understand. What is the difference between short and long connection operations, and the persistent connections that occur in some places? Use Settings
Here are the settings, we all take the HTTP1.1 protocol as an example. setting up an HTTP short connection
When you set connection:close in the Header field, the connection is closed after a request/response. set an HTTP long connection with an expiration time
Setting connection:keep-alive and Keep-alive:timeout=60 in the header field indicates that after the connection is established, the idle time exceeds 60 seconds before it expires. If you use this connection again when you are idle for the 58th second, the connection is still valid, after you have finished using it, count back and expire after 60 seconds of inactivity. set an HTTP long connection with no expiration time
Setting connection:keep-alive only in the header field indicates that the connection is permanently valid. Implementation Principle
Once you know how to set it up, start using it. However, the problem comes. Set connection:keep-alive in the request header, why is the connection idle for some time, or is it disconnected? This is because the connection field is only valid for server-side settings.
HTTP operations are request/response pairs that occur when a client makes a request and then a service-side processing request. Therefore, the end operation of an HTTP operation on the server side, the shutdown is also initiated by the server.
Next we do the test, and show code. The following tests are performed using the spring resttemplate, which encapsulates the Apache HTTP client. To facilitate the explanation of the code, the first explanation of the long connection, and finally other forms to do the test summary. Client connection failure time is greater than service-side failure time
as follows, the request log. The client sets the Connection:keep-alive and keep-alive:timeout=60, and the server sets Connection:keep-alive and keep-alive:timeout=5.
# # Client setting is valid for 60s [2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 >> "post/adx-api/api/creat Ive/upload http/1.1[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 >>" Accept:ap Plication/json, Application/*+json, text/html, Application/json, text/javascript[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?) -http-outgoing-0 >> "content-type:application/json;charset=utf-8[\r][\n" [2017-04-26 14:08:00 DEBUG] ( Org.apache.http.wire:?) -Http-outgoing-0 >> "user-agent:mozilla/5.0 (Windows NT 6.1) applewebkit/537.36 (khtml, like Gecko) chrome/31.0.16 50.16 safari/537.36[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 >>" Accept-encoding:gzip,deflate[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 >> "accept-language:zh-cn[\r][\n]" [2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 >> " Connection: keep-alive[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 >>" Keep-alive:timeo Ut=60[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 >>" content-length:396[\r " [\ n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 >>" host:bizdomain[\r][\n] "[2017-04 -26 14:08:00 Debug] (org.apache.http.wire:?)-Http-outgoing-0 >> "[\r][\n]" [2017-04-26 14:08:00 Debug] (Org.apac He.http.wire:?) -http-outgoing-0 >> "request Data" # #服务端设置有效期为5s [2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-HTTP-OUTG oing-0 << "http/1.1 ok[\r][\n]" [2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 << "Date:wed, APR 06:07:58 gmt[\r][\n]" [2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 < ;< "server:apache-coyote/1.1[\r][\n]" [2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 <& Lt "Content-tyPe:text/html;charset=utf-8[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 <<" Keep-alive:timeout=5, max=100[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 << "connection:keep-alive[\r][\n]" [2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-Http-outgoing-0 << " Transfer-encoding:chunked[\r][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 <<" [\ R][\n] "[2017-04-26 14:08:00 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 <<" 63[\r][\n] "[2017-04-26 14:08:0 0 DEBUG] (org.apache.http.wire:?)-http-outgoing-0 << "response data"
The validity period of the client setting is greater than the service side, then the actual connection is valid. Three minutes after the request again, from the connection pool lease connection, the prompt connection expired @ Wed APR 26 14:08:05, that is, after the last request of 5s invalidation, stating that the service side of the settings take effect.
[2017-04-26 14:11:00 DEBUG] (Org.apache.http.impl.conn.PoolingHttpClientConnectionManager:?) -Connection Request: [route: {}->http://bizdomain:80][total kept alive:1; route allocated:1 of; Total Allocated: 1 of
[2017-04-26 14:11:00 DEBUG] (org.apache.http.impl.conn.CPool:?)-Connection [id:2][route:{}->http:// Bizdomain:80][state:null] Expired @ Wed APR 14:08:05 gmt+08:00 2017
Source Analysis
Learn about the setup process for the connection failure time through the source code.
Org.apache.http.impl.execchain.mainclientexec#execute.//Lease Connection final from the connection pool
Httpclientconnectionmanagedconn = connrequest.get (Timeout > 0? timeout:0, timeunit.milliseconds); ...//conenction encapsulated in Connectionholder final connectionholder connholder = new Connectionholder (This.log,
This.connmanager, Managedconn);
...//The connection is in or can being brought to a re-usable state. If connection is set to close in the return value message header, False if (reusestrategy.keepalive (response, context)) {//Set the idle duration of T His connection//Remove Response message header, Keep-alive's timeout value final long duration = Keepalivestrategy.getkeepaliveduration (r
Esponse, context);
if (this.log.isDebugEnabled ()) {final String s;
if (Duration > 0) {s = "for" + Duration + "" + timeunit.milliseconds;
} else {s = "indefinitely";
} this.log.debug ("Connection can be kept alive" + s); }//Set expiration time Connholder.setvalidfor (dUration, Timeunit.milliseconds);
Connholder.markreusable (); } else {connholder.marknonreusable ();}
After the response is read, release the connection, that is: connholder.releaseconnection (). Call the Org.apache.http.impl.conn.poolinghttpclientconnectionmanager#releaseconnection method.
@Override public void Releaseconnection (final httpclientconnection managedconn, final Object state,final
Long keepalive, Final Timeunit Tunit) {args.notnull (managedconn, "Managed connection");
Synchronized (managedconn) {final Cpoolentry entry = Cpoolproxy.detach (Managedconn);
if (entry = = null) {return;
} final Managedhttpclientconnection conn = Entry.getconnection (); try {if (Conn.isopen ()) {final Timeunit Effectiveunit = Tunit! = null? tunit:time
Unit.milliseconds;
Entry.setstate (state);
Set Expiration Time Entry.updateexpiry (KeepAlive, effectiveunit);
}} finally {... }
}
}
}
And then the next HTTP operation, when you get the connection from the connection pool
org.apache.http.impl.conn.poolinghttpclientconnectionmanager# Requestconnection call Org.apache.http.pool.abstractconnpool#lease,
//Call getpoolentryblocking, Call org.apache.http.impl.conn.cpoolentry#isexpired
@Override public
boolean isexpired (final long now) {
Final Boolean expired = super.isexpired (now);
if (Expired && this.log.isDebugEnabled ()) {
//log See content
this.log.debug ("Connection" + this + "expired @" + New Date (Getexpiry ()));
}
return expired;
}
In conclusion, the actual effective time of the connection is determined according to the response setting. Other scenarios Test client Settings Connection:close
# #connection: Close request, kept alive connection is 0 [2017-04-26 13:57:00 DEBUG] ( Org.apache.http.impl.conn.PoolingHttpClientConnectionManager:?) -Connection Request: [route: {}->http://bizdomain:80][total kept alive:0; route allocated:0 of; Total Allocated: 0 of [2017-04-26 13:57:00 DEBUG] (org.apache.http.impl.conn.PoolingHttpClientConnectionManager:?)-Connection Leased: [Id:0][route: {}->http://bizdomain:80][total kept alive:0; route allocated:1 of; Total allocated:1 of 20 0] [2017-04-26 13:57:00 DEBUG] (org.apache.http.impl.execchain.MainClientExec:?)-Opening Connection {}->http:// bizdomain:80 [2017-04-26 13:57:00 DEBUG] (org.apache.http.impl.conn.DefaultHttpClientConnectionOperator:?)- Connecting to Bizdomain/127.0.0.195:80 # # Create a new connection [2017-04-26 13:57:00 DEBUG] ( Org.apache.http.impl.conn.DefaultHttpClientConnectionOperator:?) -Connection established 127.0.0.191:49239<->127.0.0.195:80 # # Client Set short connection [2017-04-26 13:57:00 DEBUG] ( Org.apache.http.wire:?) -HTTP-outgoing-0 >> "connection:close[\r][\n" # # # Server return also short connection [2017-04-26 13:57:00 DEBUG] (org.apache.http.wire:?)-HT tp-outgoing-0 << "