1. Overview

This tutorial will show how to configure a timeout with the Apache HttpClient 4.

If you want to dig deeper and learn other cool things you can do with the HttpClient – head on over to the main HttpClient tutorial.

2. Configure Timeouts via raw String Parameters

The HttpClient comes with a lot of configuration parameters – and all of these can be set in a generic, map-like manner.

There are 3 timeout parameters to configure:

1
2
3
4
5
6
7
8
9
10
DefaultHttpClient httpClient = new DefaultHttpClient();
 
int timeout = 5; // seconds
HttpParams httpParams = httpClient.getParams();
httpParams.setParameter(
  CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000);
httpParams.setParameter(
  CoreConnectionPNames.SO_TIMEOUT, timeout * 1000);
// httpParams.setParameter(
//   ClientPNames.CONN_MANAGER_TIMEOUT, new Long(timeout * 1000));

A quick note is that the last parameter – the connection manager timeout – is commented out when using the 4.3.0 or 4.3.1 versions, because of this JIRA (due in 4.3.2).

3. Configure Timeouts via the API

The more important of these parameters – namely the first two – can also be set via a more type safe API:

1
2
3
4
5
6
7
8
DefaultHttpClient httpClient = new DefaultHttpClient();
 
int timeout = 5; // seconds
HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(
  httpParams, timeout * 1000); // http.connection.timeout
HttpConnectionParams.setSoTimeout(
  httpParams, timeout * 1000); // http.socket.timeout

The third parameter doesn’t have a custom setter in HttpConnectionParams, and it will still need to be set manually via the setParameter method.

4. Configure Timeouts using the new 4.3. Builder

The fluent, builder API introduced in 4.3 provides the right way to set timeouts at a high level:

1
2
3
4
5
6
7
int timeout = 5;
RequestConfig config = RequestConfig.custom()
  .setConnectTimeout(timeout * 1000)
  .setConnectionRequestTimeout(timeout * 1000)
  .setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client =
  HttpClientBuilder.create().setDefaultRequestConfig(config).build();

That is the recommended way of configuring all three timeouts in a type-safe and readable manner.

5. Timeout Properties Explained

Now, let’s explain what these various types of timeouts mean:

  • the Connection Timeout (http.connection.timeout) – the time to establish the connection with the remote host
  • the Socket Timeout (http.socket.timeout) – the time waiting for data – after the connection was established; maximum time of inactivity between two data packets
  • the Connection Manager Timeout (http.connection-manager.timeout) – the time to wait for a connection from the connection manager/pool

The first two parameters – the connection and socket timeouts – are the most important, but setting a timeout for obtaining a connection is definitely important in high load scenarios, which is why the third parameter shouldn’t be ignored.

6. Using the HttpClient

After being configured, the client can not be used to perform HTTP requests:

1
2
3
4
HttpGet getMethod = new HttpGet("http://host:8080/path");
HttpResponse response = httpClient.execute(getMethod);
System.out.println(
  "HTTP Status of response: " + response.getStatusLine().getStatusCode());

With the previously defined client, the connection to the host will time out in 5 seconds, and if the connection is established but no data is received, the timeout will also be 5 additional seconds.

Note that the connection timeout will result in an org.apache.http.conn.ConnectTimeoutException being thrown, while socket timeout will result in java.net.SocketTimeoutException.

7. Hard Timeout

While setting timeouts on establishing the HTTP connection and not receiving data is very useful, sometimes we need to set a hard timeout for the entire request.

For example, the download of a potentially large file fits into this category – in this case, the connection may be successfully established, data may be consistently coming through, but we still need to ensure that the operation doesn’t go over some specific time threshold.

HttpClient doesn’t have any configuration that allows us to set an overall timeout for a request; it does, however, provide abort functionality for requests, so we can leverage that mechanism to implement a simple timeout mechanism:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
HttpGet getMethod = new HttpGet(
 
int hardTimeout = 5; // seconds
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        if (getMethod != null) {
            getMethod.abort();
        }
    }
};
new Timer(true).schedule(task, hardTimeout * 1000);
 
HttpResponse response = httpClient.execute(getMethod);
System.out.println(
  "HTTP Status of response: " + response.getStatusLine().getStatusCode());

We’re making use of the java.util.Timer and java.util.TimerTask to set up a simple delayed task which aborts the HTTP GET request after a 5 seconds hard timeout.

8. Timeout and DNS Round Robin – something to be aware of

It is quite common that some larger domains will be using a DNS round robin configuration – essentially having the same domain mapped to multiple IP addresses. This introduces a new challenge for a timeout against such a domain, simply because of the way HttpClient will try to connect to that domain that times out:

  • HttpClient gets the list of IP routes to that domain
  • it tries the first one – that times out (with the timeouts we configure)
  • it tries the second one – that also times out
  • and so on …

So, as you can see – the overall operation will not time out when we expect it to. Instead – it will time out when all the possible routes have timed out, and what it more – this will happen completely transparently for the client (unless you have your log configured at the DEBUG level). Here is a simple example you can run and replicate this issue:

1
2
3
4
5
6
7
8
9
10
int timeout = 3;
RequestConfig config = RequestConfig.custom().
  setConnectTimeout(timeout * 1000).
  setConnectionRequestTimeout(timeout * 1000).
  setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = HttpClientBuilder.create()
  .setDefaultRequestConfig(config).build();
 
HttpGet request = new HttpGet("http://www.google.com:81");
response = client.execute(request);

You will notice the retrying logic with a DEBUG log level:

1
2
3
4
5
6
7
8
9
10
11
12
DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.212:81
DEBUG o.a.h.i.c.HttpClientConnectionOperator -
 Connect to www.google.com/173.194.34.212:81 timed out. Connection will be retried using another IP address
 
DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.208:81
DEBUG o.a.h.i.c.HttpClientConnectionOperator -
 Connect to www.google.com/173.194.34.208:81 timed out. Connection will be retried using another IP address
 
DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.209:81
DEBUG o.a.h.i.c.HttpClientConnectionOperator -
 Connect to www.google.com/173.194.34.209:81 timed out. Connection will be retried using another IP address
//...

9. Conclusion

This tutorial discussed how to configure the various types of timeouts available for an HttpClient. It also illustrated a simple mechanism for hard timeout of an ongoing HTTP connection.

The implementation of these examples can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

最新文章

  1. msysGit管理GitHub代码
  2. JavaScript 的性能优化:加载和执行
  3. 【BZOJ】1051: [HAOI2006]受欢迎的牛(tarjan)
  4. 奇葩的SQL*Net more data from client等待,导致批处理巨慢
  5. STL学习系列之一——标准模板库STL介绍
  6. Docker最全教程之Ubuntu下安装Docker(十四)
  7. 怎样利用ADO中的adoquery进行缓存更新?????(100分)
  8. 【PMP】组织结构类型
  9. ARM基础
  10. Django model中设置多个字段联合唯一约束
  11. 特征选择:方差选择法、卡方检验、互信息法、递归特征消除、L1范数、树模型
  12. java 元数据
  13. NOIP 2016 迟来的满贯
  14. SM系列国密算法(转)
  15. 为什么要使用叶脊(leaf-spine)拓扑网络?
  16. win7下本地运行spark以及spark.sql.warehouse.dir设置
  17. ubuntu 18 下配置 WebStorm 编译 sass
  18. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_值类型的装箱和拆箱(二)
  19. spring boot 引用外部配置文件
  20. Content encoding error问题解决方法

热门文章

  1. bzoj 3924 [Zjoi2015]幻想乡战略游戏——动态点分治(暴力移动找重心)
  2. mac下搭建appium记录
  3. mysql5.7.12/13在安装新实例时报错:InnoDB: auto-extending data file ./ibdata1 is of a different size 640 pages (rounded down to MB) than specified in the .cnf file: initial 768 pages, max 0 (relevant if non-zero
  4. jquery 等html加载完成再绑定事件
  5. 使用WebClient與HttpWebRequest的差異
  6. 第七章 : Git 介绍 (下)[Learn Android Studio 汉化教程]
  7. div+css 命名规则
  8. verilog 计算机网络 仿真 激励 pcap
  9. IIS 禁止访问:在 Web 服务器上已拒绝目录列表
  10. 12 并发编程-(线程)-线程queue&进程池与线程池