一定要为HttpUrlConnection设置connectTimeout属性以防止连接被阻塞

    我们有一个项目中用到了多个子项目,即将多个子项目的连接地址整合在一起。在客户部署环境中,有一个主终端,负责接受用户登陆,在登陆时,由用户选择最终要登陆的子系统。当输入登陆信息之后,由主终端负责解析用户名和密码,待验证通过之后,再通过主终端负责将用户信息直接发往子系统并通过子系统接口转入到后台操作界面。整个流程就类似于一个统一授权中心,由主终端负责用户授权和访问,在获得授权之后,就可以直接操作子系统了。
    前几天在客户方将数据copy回来并进行分析时,发现在首页显示其它子系统时非常的慢,甚至慢到不能忍受的地步。但这种情况在客户环境中并没有发现。待仔细地查看了数据逻辑处理,发现了后台在列举子系统数据时,首先需要判断当前的子系统是否能够连接,即有一个如下的连接代码:

/** 指定的子系统是否是断开连接的 */
	public static boolean isOffline(SubSystem subSystem) {
		String url = subSystem.getRequestAddress();
		try {
			URL requestURL = new URL(url);
			HttpURLConnection urlConnection = (HttpURLConnection) requestURL.openConnection();
			urlConnection.connect();
			urlConnection.disconnect();
			return false;
		} catch(Exception ignore) {
			return true;
		}
	}

    就是由于这段代码,导致系统长时间停留在这段处理代码中。发现代码在处理connect时,半天无法响应。由于数据是在客户方copy回来了,所要连接的子系统的ip地址为192.168.1.99,而当前在笔者机器的ip为192.168.0.*,即在连接子系统时会无法连接,但这个连接不到所返回的时间也太长了。
    笔者测试了下时间,这段连接不的代码在windows下的异常时间(即开始连接到发生异常的时间)为20秒,而linux下这个时间就长了,达到了180秒,即java要经过180秒才能发现这个连接根本就连接不上。
    笔者又在cmd下通过ping,来测试一下连接时间,也是发现连接时间长时间也没有响应。

    笔者将子系统的ip地址,进行了修改,修改到本机上,但端口并没有修改,即仍然也连接不上这个子系统(客户方端口为1001,而本机上端口为5555)。仍然使用以上代码,发现代码,在不到1秒的时间之内就返回了。即虽然连接不上指定的端口,但能够连接到这个ip。后又试了下直接连

http://www.163.com:5555

    然而,即使是不存在的ip地址,当笔者将连接的ip修改为一个内网的不存在的ip,如192.168.0.XX(这个ip肯定是ping不通的),但发现处理代码仍然在第一时间(比正常时间稍长,但也只有2-3秒之间)就返回了。
    最终的结论就是,这个到指定ip的连接取决于这个ip是否能够被有效地连接,以及是否能够快速地响应连接与否。如果不能连接,但路由器能够及时响应错误信息,也可以快速地返回;相反,如果路由器半天不能响应,就会导致代码在执行时也不会及时的响应。

    最终的解决方法,就是需要给连接代码追加一个超时设置,即通过以下设置代码追加一个超时期限:

urlConnection.setConnectTimeout(3000);

    这时,我们设置为超时时间为3秒,如果3秒内不能连接就被认为是有错误发生,从而有效地避免了由于ip不通导致连接不上的问题。并且,这个时间只是指建立socket的时间,而并不是指发送数据以及数据传输的时间。所以在一般的连接处理中,这个时间已经是非常地长了,不同的项目可以根据具体设置加以调整。但无论如果,给一个url请求,追加一个合适的超时时间是必须的,以保证正常的数据请求都能正确地处理,防止由于暂时的连接错误导致系统不能及时地响应。

转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/must-set-connecttimeout-for-httpurlconnection-to-invoid-connect-block.html

相关文章:

作者: flym

I am flym,the master of the site:)

发表评论

邮箱地址不会被公开。 必填项已用*标注