The use of httpclient must know the parameter settings and code, the existence of the risk

Source: Internet
Author: User
Tags connection pooling log log

Conclusion: If you use HttpClient 3.1 concurrent volume of the project, it is best to upgrade to httpclient4.2.3, to ensure that the concurrency is large when the resistance to live.   HttpClient 4.3.3, there are still some bugs, or 4.2.x stable version of it. Take inventory items as an example:

httpclient Day concurrency in 1500w around, peak one second 7 million.

In the previous use process, there has been a large number of

org.apache.http.conn.ConnectionPoolTimeoutException:Timeout Waiting for Connection from Pool
at org. Apache. http. Impl. Conn. Poolingclientconnectionmanager. leaseconnection ( Poolingclientconnectionmanager. Java :232)
at org. Apache. http. Impl. Conn. Poolingclientconnectionmanager $ 1. getconnection ( Poolingclientconnectionmanager. Java :199)
at org. Apache. http. Impl. client. Defaultrequestdirector. Execute ( defaultrequestdirector. Java :456In addition to viewing threads through Jstack, you will find: "pool-21-thread-3" prio=10 tid=0x00007f6b7c002800 nid=0x40ff waiting on condition [ 0X00007F6B37020000]
Java.lang.Thread.State:TIMED_WAITING (parking)
At Sun.misc.Unsafe.park (Native Method)
-Parking to wait for <0x00000000f97918b8> (a java.util.concurrent.locks.abstractqueuedsynchronizer$ Conditionobject)
At Java.util.concurrent.locks.LockSupport.parkUntil (locksupport.java:239)
At Java.util.concurrent.locks.abstractqueuedsynchronizer$conditionobject.awaituntil ( abstractqueuedsynchronizer.java:2072)
At Org.apache.http.pool.PoolEntryFuture.await (poolentryfuture.java:129)
At Org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking (abstractconnpool.java:281)
At org.apache.http.pool.abstractconnpool.access$000 (abstractconnpool.java:62)
At Org.apache.http.pool.abstractconnpool$2.getpoolentry (abstractconnpool.java:176)
At Org.apache.http.pool.abstractconnpool$2.getpoolentry (abstractconnpool.java:172)
At Org.apache.http.pool.PoolEntryFuture.get (poolentryfuture.java:100)
At Org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection (Poolingclientconnectionmanager.java     : 212) Problem: Because of the use of connection pooling, but not enough connection, resulting in a lot of waiting, and this wait has a snowball effect (and the trading group recently used Apache common DBCP the risk is similar).     Solution finally we set some reasonable parameter values, so we have not encountered any problems at present.   Thinking in fact the cause of the problem is that we do not understand some parameters, arbitrarily set its value, no problem is good, there are problems difficult to troubleshoot the cause, so I use the httpclient must be set parameters and code writing and troubleshooting methods summarized, for reference. Parameter settings 1, httpclient 4.2.3 httpparams params = new Basichttpparams (); Set the connection time-out period Integer connection_timeout = 2 * 1000;//Set Request timed out 2 seconds based on business adjustmentInteger so_timeout = 2 * 1000;//Set wait data timeout 2 seconds according to business adjustment //Defines the millisecond time-out period used when retrieving managedclientconnection instances from Clientconnectionmanager //This parameter expects to get a value of type Java.lang.Long. If this parameter is not set, the default equals Connection_timeout, so be sure to setLong conn_manager_timeout = 500L;//This value is when the connection is not enough to wait for time-out, be sure to set it, and not too big ()

Params.setintparameter (Coreconnectionpnames.connection_timeout, connection_timeout); Params.setintparameter (Coreconnectionpnames.so_timeout, so_timeout); Params.setlongparameter (Clientpnames.conn_manager_timeout, conn_manager_timeout);    Test whether the connection is available Params.setbooleanparameter (Coreconnectionpnames.stale_connection_check, True) before submitting the request; Poolingclientconnectionmanager conmgr = new Poolingclientconnectionmanager (); Conmgr.setmaxtotal (200); //Set the maximum number of connections for the entire connection pool depending on your scenario //is the default maximum connection for routing (this value defaults to 2), the limit quantity actually used Defaultmaxperroute is not maxtotal. Set too small to support large concurrency (connectionpooltimeoutexception:timeout waiting for connection from pool), routing is a subdivision of Maxtotal. Conmgr.setdefaultmaxperroute (Conmgr.getmaxtotal ());//(Currently there is only one route, so let him be equal to the maximum)//Set the HTTP client retry count by default 3 times Httpclient.sethttprequestretryhandler (New Defaulthttprequestretryhandler (0, false) is currently disabled (if the project volume is not available); The differences between Maxttotal and Defaultmaxperroute are explained here:

1, Maxttotal is the size of the whole pond;

2. Defaultmaxperroute is a subdivision of the maxtotal based on the host connected to it, such as maxttotal=400 defaultmaxperroute=200 and I Only connect to http:// sishuok.com, the maximum concurrency to this host is only 200, not 400, while I connect to http://sishuok.com and http:// qq.com, the maximum concurrency for each host is only 200, which adds up to 400 (but not more than 400); So the setting that works is Defaultmaxperroute.    

2, httpclient 3.1 httpconnectionmanagerparams params = new Httpconnectionmanagerparams (); Params.setconnectiontimeout (2000); Params.setsotimeout (2000); Maximum number of connections params.setmaxtotalconnections (500); Params.setdefaultmaxconnectionsperhost (500); Params.setstalecheckingenabled (TRUE);   Connectionmanager.setparams (params); Httpclientparams httpclientparams = new Httpclientparams (); Setting the connection timeout for httpclient, the connection timeout for Connection Manager settings is useless httpclientparams.setconnectionmanagertimeout (5000); Equivalent to Conn_manager_timeout httpClient in 4.2.3 = new HttpClient (ConnectionManager);   Httpclient.setparams (Httpclientparams); In addition, set the number of HTTP client retries, the default is 3 times, is currently disabled (if the project volume is not, this default) Httpclientparams.setparameter (Httpmethodparams.retry_handler     , new Defaulthttpmethodretryhandler (0, false)); The parameters are similar and not much explained; code notation

1, HttpClient 4.2.3

HttpResponse response = null; Httpentity entity = NULL;

try {

HttpGet get = new HttpGet ();

String url = "http://hc.apache.org/";

Get.seturi (new URI (URL));

Response = Gethttpclient (). Execute (GET); //Processing Response}

catch (Exception e) {

Handling Exceptions

}

finally {

if (response! = NULL) {

Entityutils.consume (Response.getentity ());

will automatically release the connection

}//The following methods are also possible, but there are some risks;

InputStream is = Response.getentity (). getcontent ();  Is.close (); }

2, httpclient 3.1 postmethod postmethod = new Postmethod (Yxurl);

try {

Httpclient.executemethod (Postmethod);

} catch (Exception e) {

Handle Exception} finally {

if (Postmethod! = null) {

Do not forget to release, try to achieve through this method,

Postmethod.releaseconnection (); There is a risk, do not use

Postmethod.setparameter ("Connection", "close"); InputStream is = Postmethod.getresponsebodyasstream ();

Is.clsoe () will also close and release the connected

}} The risk exists

1, HttpClient 4.2.3 When the connection is released

if (Managedconn.isopen () &&!managedconn.ismarkedreusable ()) {//If the connection is open and not reusable (not keepalive) close socket

try {managedconn.shutdown ();

} catch (IOException Iox) {

if (this.log.isDebugEnabled ()) {

This.log.debug ("I/O exception shutting down released connection", Iox); }}}//Only reusable connections can be kept alive

if (managedconn.ismarkedreusable ()) {Entry.updateexpiry (keepalive, Tunit! = null? tunit:TimeUnit.MILLISECONDS);

if (this.log.isDebugEnabled ()) {

String s; if (KeepAlive > 0) {

s = "for" + KeepAlive + "" + Tunit;

} else {

s = "indefinitely";

}

This.log.debug ("Connection" + Format (Entry) + "can be kept alive" + s);

}} No Risk


2, HttpClient 3.1 1,

If you go to the http1.1 protocol: if the proxy-connection/connection request header is set to close, the socket will be closed, or the two headers will not be equal to close also automatically closed;

2, if it is keep-alive, will not be closed;

3, if the protocol is less than or equal to the http1.0 protocol is not a problem; call releaseconnection close the socket;

4, other circumstances will not close; that is, if you go http1.1 and do not set the relevant parameters, then the socket is actually not closed, it may cause a lot of time_wait; so if it is a short connection, the recommended setting Postmethod.setparameter (" Connection "," close ").

Other precautions:

1, use keep-alive must set the Content-length head (otherwise it is not a long connection).

2, when using httpclient3.1 (4.2.3 no problem); try not to call byte[] Getresponsebody (): Because if the content-length is not set or the data transmitted is greater than 1M, there will be a large number of log Log.warn as follows (    "Going to buffer response body of large or unknown size." + "Using Getresponsebodyasstream instead is recommended."); If the parameter can be set greater than 1M, but 1 is no way, do not call byte[] Getresponsebody () Httpclientparams.setlongparameter (       Httpmethodparams.buffer_warn_trigger_limit, 2L * 1024 * 1024); 3, lock HttpClient 3.1

Using Synchronized+wait+notifyall, there are two problems, the volume of large synchronized slow and notifyall may cause thread starvation;

HttpClient 4.2.3 uses Reentrantlock (default non-fairness) + Condition (one per thread).

here is a test: Http://java.dzone.com/articles/synchronized-vs-lock, in my native (jdk1.6.0_43) test Results Detail lock advantage is relatively large 1x synchronized {} with + threads took 2.621 seconds 1x Lock.lock ()/unlock () with threads took 1.951 seconds 1x Atomicinteger with + threads took 4.113 seconds 1x synchronized {} with + threads took 2.621 seconds 1x Loc K.lock ()/unlock () with threads took 1.983 seconds That's why using HttpClient 3.1 in inventory projects still has a lot of wait, and httpclient4.2.3 a A problem that is not in the area.

If you have any questions, please enlighten me.


The use of httpclient must know the parameter settings and code, the existence of the risk

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.