If ConnectTimeoutException occurs in HttpClient, the connection timeout is poor. We can use the logic code to go to HttpClient optimization or to optimize the request server. I will introduce optimizing the business logic below.
In a recent project, HttpClient needs to be used to request multiple remote servers. Because the interface is called a little frequently, many ConnectTimeoutException occurs, so the program is optimized.
The optimization of business logic and the optimization of reducing the number of requests will not be mentioned. Next we will focus on the optimization of HttpClient.
First look at the previous Code, each request will create an HttpClient, the Code is as follows:
| The Code is as follows: |
Copy code |
|
HttpClient client = getHttpClient (5000,500 0 );
GetMethod getMethod = new GetMethod (url );
GetMethod. setQueryString (parameter );
Byte [] responseBody = null;
Try {
Int statusCode = client.exe cuteMethod (getMethod );
If (statusCode! = HttpStatus. SC _ OK ){
Logger. error ("error! "+ Url +", statusCode "+ statusCode );
}
ResponseBody = getMethod. getResponseBody ();
} Catch (IOException e ){
Logger. error ("error! "+ Url, e );
} Finally {
GetMethod. releaseConnection ();
} |
This is the simplest code. Many examples start with this. If a small number of requests are okay and requests are frequent, this code is not very good. (Note that the connection must be released after the connection is used up ).
First, HttpClient can be shared to reduce the overhead of creating HttpClient. Of course, if your application does not call HttpClient frequently, it is unnecessary to share it. After all, it is not safe to maintain an idle httpClient object in the memory.
Second, Connection can be reused to reduce the overhead of establishing a Connection.
You can use MultiThreadedHttpConnectionManager under multiple threads to manage HttpConnection and HttpClient. The HttpClient managed by MultiThreadedHttpConnectionManager is thread-safe and can be used as a singleton. However, it is worth noting that each thread should have its own HttpMethod, HttpState, and HttpConfiguration to distinguish the host and HttpSession of each request. As follows:
| The Code is as follows: |
Copy code |
|
Private static MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager ();
Private HttpClient client = new HttpClient (httpConnectionManager ); |
After definition, initialize relevant parameters in the static Block
| The Code is as follows: |
Copy code |
|
Static {
// The maximum number of connections per host and the total maximum number of connections are distinguished by setting the host in hosfConfiguration.
Client. getHttpConnectionManager (). getParams (). setdefamaxmaxconnectionsperhost (8 );
Client. getHttpConnectionManager (). getParams (). setMaxTotalConnections (48 );
Client. getHttpConnectionManager (). getParams (). setConnectionTimeout (5000 );
Client. getHttpConnectionManager (). getParams (). setSoTimeout (5000 );
Client. getHttpConnectionManager (). getParams (). setTcpNoDelay (true );
Client. getHttpConnectionManager (). getParams (). setLinger (1000 );
// If the request fails, three attempts will be made.
Client. getHttpConnectionManager (). getParams (). setParameter (HttpMethodParams. RETRY_HANDLER, new DefaultHttpMethodRetryHandler ());
} |
Some parameters in HttpConfiguration are helpful for improving performance, mainly described as follows:
The defamaxmaxconnectionsperhost parameter defines the maximum number of connections allowed for each host. The default value is 2. This parameter can only be used for some specific httpConnectionManager, such as MultiThreadedHttpConnectionManager.
The MaxTotalConnections parameter indicates the maximum number of connections managed by httpConnectionManager. The default value is 20. The same parameter. this parameter is only useful in some specific httpConnectionManager.
SetTcpNoDelay (true) sets whether to enable the Nagle algorithm. If it is set to true, the Nagle algorithm is disabled. The default value is false (that is, the Nagle algorithm is enabled by default ). The Nagle algorithm tries to reduce the number of shards to save bandwidth. When applications want to reduce network latency and improve performance, they can disable the Nagle algorithm so that data will be sent earlier, but this increases network consumption.
SetLinger (1000) sets the socket delay close time. If the value is 0, this option is disabled. If the value is-1, the default setting of JRE is used.
The setStaleCheckingEnabled (true) parameter sets whether to enable the old Connection check, which is enabled by default. Disabling the old Connection check can improve performance a little, but increases the risk of I/O errors (when the server closes the connection ). Enabling this option will check whether the connection is available every time you use the old connection. This takes about 15-30 ms [3].
Then, create your own HttpMethod in each thread code.
Another important optimization point is to use the request/response entity stream, especially when the number of requests is large, A large entity is directly sent or received without being cached in the memory. Using a stream can effectively improve performance. Although these entities can be strings or byte arrays, they can easily cause memory leakage. You must use them carefully because they are cached in the memory.
GetResponseBodyAsStream () of method is used to replace getResponseBody () and getResponseBodyAsString:
| The Code is as follows: |
Copy code |
|
HttpClient httpclient = new HttpClient ();
GetMethod httpget = new GetMethod ("http://www.bKjia. c0m /");
Try {
Httpclient.exe cuteMethod (httpget );
Reader reader = new InputStreamReader (httpget. getResponseBodyAsStream (), httpget. getResponseCharSet ());
// Consume the response entity
} Finally {
Httpget. releaseConnection ();
} |
For request streams, You Can Customize various flows by implementing RequestEntity. httpclient includes several common implementations, such as FileRequestEntity, ByteArrayRequestEntity, StringRequestEntity, and MultipartRequestEntity. Example:
| The Code is as follows: |
Copy code |
|
File myfile = new File ("myfile.txt ");
PostMethod httppost = new PostMethod ("/stuff ");
Httppost. setRequestEntity (new FileRequestEntity (myfile )); |
If the communication between the client and the server does not require session persistence, you can disable cookies to improve performance, such as Spider crawlers. As follows:
| The Code is as follows: |
Copy code |
|
HttpMethod method = new GetMethod ();
Method. getParams (). setCookiePolicy (CookiePolicy. IGNORE_COOKIES );
Method. setRequestHeader ("Cookie", "special-cookie = value "); |
For more information about HttpClient timeout, click three timeout settings in httpClient in Java.