tomcat 中close_wait 不释放导致tomcat频繁假死

tomcat 中close_wait 不释放导致tomcat频繁假死

遇到的问题

最近自己做了一个小程序项目发现在发布后tomcat 过一段时间后就假死,一开始查询了了用户量发现用户一天登陆3000+以为是用户量的问题,我修改了tomcat 配置,增大了访问量的线程,可是发现到了晚上有挂了,查询线程后发现,连接被close_wait 沾满,且close_wait 不断增加,最后tomcat无法访问

报错信息

在这里插入图片描述

解决方案

单从报错信息可以看出是 443 端口的问题,我443 配置了https,我一开始以为是https 的配置,查了文档发现配置没有问题,网上查询说的httpClient 没有关闭 查询了我的代码 ,把没有的close 的httpClient 全部加上close ,发现还是无效,崩溃。继续找解决方案,但是tomcat 抗不住老是爆炸,只能一次次重启中度日,找大神问(这里特别感谢下咕泡学院的Mic老师),大神指导说你的httpClient 没关,可是事实是我关了,但是这时候我截日志的是否发现了一个异常在这里插入图片描述这个异常在项目运行,甚至假死的状态的都不会抛出,但是在关闭tomcat 的时候会抛出,定位到代码 发现是取小程获取openid 的时候socket 问题,但是我httpclient 关闭了,为啥这个连接还保持着,找HttpClient 相关文档,发现我的HttpClient 未做时间限制,下面列出修改前后的代码
修改前的代码:

	private static HttpResponse sendRequest(DefaultHttpClient httpclient,
                                            HttpUriRequest httpost) {
		logger.info("execute post...");
		HttpResponse response = null;
		
		try {
			response = httpclient.execute(httpost);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return response;
	}

修改后的的代码:

private static HttpResponse sendRequest(DefaultHttpClient httpclient,
                                            HttpUriRequest httpost) {
	   logger.info("execute post...");
		HttpResponse response = null;
		
		try {
            httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,4000);//连接时间
			httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,4000); 
			response = httpclient.execute(httpost);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			httpost.abort();
			httpclient.close();
		}
		return response;
	}

改好发布,发现异常锐减,修改前的方法是网上直接复制的, httpclient 方法没有加 连接时间和超时时间 自己测试发现没有就粘上去发布,实际应用生产的时候出了问题,坑坑坑,到了这一步发现之前对httpClient还有很多需要优化的地方,找了资料,把方法重写
最终版:

public static String post(String url, Map<String, String> params) {
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();

		String body = null;
		StringBuffer paramsd = new StringBuffer();

		paramsd.append("appid=" + params.get("appid"));
		paramsd.append("&");
		paramsd.append("secret=" + params.get("secret"));
		paramsd.append("&");
		paramsd.append("js_code=" + params.get("js_code"));
		paramsd.append("&");
		paramsd.append("grant_type=" + params.get("grant_type"));
		HttpGet httpGet = new HttpGet(url + "?" + paramsd);
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 配置信息
			RequestConfig requestConfig = RequestConfig.custom()
					// 设置连接超时时间(单位毫秒)
					.setConnectTimeout(4000)
					// 设置请求超时时间(单位毫秒)
					.setConnectionRequestTimeout(4000)
					// socket读写超时时间(单位毫秒)
					.setSocketTimeout(4000)
					// 设置是否允许重定向(默认为true)
					.setRedirectsEnabled(true).build();

			// 将上面的配置信息 运用到这个Get请求里
			httpGet.setConfig(requestConfig);

			// 由客户端执行(发送)Get请求
			response = httpClient.execute(httpGet);

			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
//			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
			 return EntityUtils.toString(responseEntity);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return body;
	}

发布 问题解决,这个文章对高手来说可能一文不值,但是我觉得我要记下来为后来同样遇到这个问题的哥们提供一个可能解决方案。

  • 13
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值