有关HTTP通信的超时设置

有关HTTP通信的超时设置

      • 问题描述
      • HttpClient的超时设置
      • Qt C++中的HTTP超时设置
      • 结语

问题描述

  企业内部用OpenStack Swift搭建了一个私有云存储系统,按理说只要存储空间足够,I/O吞吐应该是杠杠的。
(论证阶段进行验证用的是Java的HttpClient组件,一直很流畅)
  结果应用系统使用的是Qt C++(5.9)开发的客户端,分片上传大文件时总是出现不稳定(而且才2个线程)。
  经过对比测试,初步定位在HTTP通信的超时设置上。

HttpClient的超时设置

  相比之下,Java语言的HTTP通信要比Qt C++的要完备、成熟得多。以下是Java客户端的代码:

	……
	//构建GET方法
	HttpGet get = new HttpGet(url);
	//0321设置超时
	RequestConfig config = RequestConfig.custom().setConnectTimeout(toc.getConn() )
					 						 	 .setConnectionRequestTimeout(toc.getConnReq() )
					 						 	 .setSocketTimeout(toc.getSocket() ).build();
	get.setConfig(config);

	if(!this.collectUtil.isEmpty(header) ) { //0528增补HTTP请求头部
		for(String key : header.keySet()) {
			get.setHeader(key, header.get(key) );
		}
	}

	//客户端执行
	HttpResponse resp = HttpClients.createDefault().execute(get);
	//返回状态
	int statusCode = resp.getStatusLine().getStatusCode();
	……

  上述是使用Apache HttpClient组件,使用GET方法请求指定URL的代码片段。
  代码片段中设置了请求超时(RequestConfig即是),如果不设置超时,则无需定义config变量以及调用setConfig方法即可。

  代码中,请求超时包括三个部分:

  • 连接超时(ConnectTimeout) — 请求1个连接的超时(单位:ms)
  • 连接请求超时(ConnectionRequestTimeout) — 建立1个连接的超时(单位:ms)
  • 套接字超时(SocketTimeout) — 等待数据(I/O)的超时(单位:ms)

   以上3个超时的定义,也是按照的通信时序。 对于这3个超时的设定,是统一的:

  • 正值即设定值;
  • 0值表示无限超时;
  • -1(默认值)表示系统默认值。

  以下是Apache HttpClient组件(4.5.12)默认配置相关代码:

	Builder() {
		super();
		this.staleConnectionCheckEnabled = false;
		this.redirectsEnabled = true;
		this.maxRedirects = 50;
		this.relativeRedirectsAllowed = true;
		this.authenticationEnabled = true;
		this.connectionRequestTimeout = -1;
		this.connectTimeout = -1;
		this.socketTimeout = -1;
		this.contentCompressionEnabled = true;
		this.normalizeUri = true;
	}

  这里的Builder即是RequestConfig.Builder。

Qt C++中的HTTP超时设置

  相比之下,Qt C++实现HTTP超时设置就有点五花八门了:不同版本的实现方式不一样。
  依据开发文档的检索,Qt从5.15才开始定义了QNetworkRequest::DefaultTransferTimeoutConstant(其值为30000ms)。
  在我们5.9的版本中,使用的是计时器(QTimer)来实现的超时管理:即发起请求后开始计时,直到通信完成,或者超时才停止/销毁。所以该超时设置应该是按照上述的套接字超时来设置,一般地,应该设置稍大一些,例如5.15中的30s。
  当然,如果没有特别要求,无需额外设置,即使用系统默认值即可。

结语

  1. 对于不同系统,例如:Java vs Qt C++,对于通信超时的定义可能有所不同,需要区别对待。
  2. 除非您对超时设置比较熟悉,否则不建议您额外设置,使用系统默认即可。

你可能感兴趣的:(HttpClient,编程,JAVA)