上篇中提到解决的一个问题是mysql驱动报的:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

昨天最后的“解决方法”是增加Mysql的max_connections,当时就觉得其实根本没有解决问题,果然今天早上来一压问题又重现了:

[2013-06-20 10:43:13.727][ERROR]执行存储过程{SEL_LocatlityRelationByName}出错:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.GeneratedConstructorAccessor55.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1121)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:357)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2479)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2516)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2301)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.GeneratedConstructorAccessor46.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:416)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:346)
at java.sql.DriverManager.getConnection(DriverManager.java:579)
at java.sql.DriverManager.getConnection(DriverManager.java:221)
at com.iflytek.ossp.vaserver.data.SQLHelper.getConnection(SQLHelper.java:84)
at com.iflytek.ossp.vaserver.data.SQLHelper.getResultSetExecProc(SQLHelper.java:46)
at com.iflytek.ossp.vaserver.data.VADataHandler.getLocRelation(VADataHandler.java:87)
at com.iflytek.ossp.vaserver.cmd.weather.WeatherQueryClient.getCmccCityId(WeatherQueryClient.java:481)
at com.iflytek.ossp.vaserver.cmd.weather.WeatherQueryClient.getMLUInfo(WeatherQueryClient.java:555)
at com.iflytek.ossp.vaserver.cmd.mainlist.MainListUpdate.businessProcess(MainListUpdate.java:68)
at com.iflytek.ossp.vaserver.cmd.mainlist.MainListUpdate.execute(MainListUpdate.java:26)
at com.iflytek.ossp.vaserver.VAClientHttpServlet.businessProc(VAClientHttpServlet.java:133)
at com.iflytek.ossp.vaserver.VAClientHttpServlet.doPost(VAClientHttpServlet.java:78)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.iflytek.ossp.vaserver.EncodingFilter.doFilter(EncodingFilter.java:45)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.net.SocketException: 打开的文件过多
at java.net.Socket.createImpl(Socket.java:447)
at java.net.Socket.<init>(Socket.java:421)
at java.net.Socket.<init>(Socket.java:241)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:259)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:307)
... 43 more 

不过这次我将堆栈信息打的更为详细了点,仔细一看注意到了上面标红的一行:Caused by: java.net.SocketException: 打开的文件过多。打开文件太多,到底打开什么文件太多呢?SocketException让我想到了TIME_WAIT,于是在压力测试进行的过程中查看了下TIME_WAIT执行下面的命令:

netstat -nt | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}' 

发现TIME_WAIT一路飙升最后达到了14000多:

于是我怀疑是因为TIME_WAIT过大导致的,于是Google解决TIME_WAIT过大的方法:

1)通过增加可用端口:

用下面的命令可以查看系统当前使用的端口区间:

 sysctl -a | grep port

使用下面的命令可以增加系统使用的端口区间:

shell> echo "net.ipv4.ip_local_port_range = 10240 61000" >> /etc/sysctl.conf
shell> sysctl -p

结果TIME_WAIT依然很大,mysql还是报之前的错误。

2)修改系统内核参数tcp_tw_reusetcp_tw_recycle

可以用下面的命令查看这两个参数的值:

sysctl -a | grep tcp_tw_reuse
sysctl -a | grep tcp_tw_recycle

默认这两个参数都是0,这两个参数的作用是让系统能重用端口。(注:通过sysctl命令修改内核参数,重启后会还原,要想持久化可以参考修改端口的方法。)

注意tcp_tw_recycle只有在tcp_tw_reuse为1的时候置为1才有效。

结果:发现TIME_WAIT明显减少了,最高维持在3300多:

但是mysql的问题依然存在,但似乎减少了点。

3)网上有说在NAT环境下打开tcp_tw_recycle可能会引起其他更复杂的网络问题,具体参看官方文档:https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt。于是我使用了网上说的另外一种解决TIME_WAIT过大的问题:修改系统参数tcp_max_tw_buckets,通过设置它系统会将多余的TIME_WAIT删除掉。默认该值为18000:

我将该值设置为5000:

shell> sysctl net.ipv4.tcp_max_tw_buckets=

结果TIME_WAIT相比第2)种方法没有明显减少,问题依然存在。

难道不是因为TIME_WAIT过大造成的?产生这个异常到到底说明了什么:

这些异常指出操作系统 (OS) 资源问题和操作系统与 JVM 进程用完文件描述符的原因。

难道真的是系统文件描述符用完了!用过ulimit -a命令可以查看系统最大的打开文件数:

通过下面的命令可以增加这个值:

ulimit -n 

但是就算这样能解决我的问题,也是治标不治本。于是我重新仔细检查了下日志,因为之前一直怀疑是mysql的问题,所以只关心mysql的问题。结果发现另外一处发起http请求的时候出现了类似的异常信息:

java.net.SocketException: 打开的文件过多

于是最后将问题定位在了下面的发起http请求的代码中:

public boolean get(String url, StringBuffer content, String encoding) {
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod(url);
// 设置url连接超时
client.getHttpConnectionManager().getParams()
.setConnectionTimeout(timeOut);
// 设置读取数据超时
client.getHttpConnectionManager().getParams().setSoTimeout(timeOut); method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,
encoding); try {
client.executeMethod(method);
String respString = method.getResponseBodyAsString();
content.append(respString); } catch (ConnectTimeoutException e) {
errorString = "Connect Timeout:" + url;
return false;
} catch (SocketTimeoutException e) {
errorString = "Socket Timeout:" + url;
return false;
} catch (IOException e) {
errorString = e.toString();
return false;
} finally {
method.releaseConnection();
} return true;
}

最后证明真的是因为http请求没有释放socket资源造成的,mysql只是被“坑”了而已。

最后给出修改后的代码:

public boolean get(String url, StringBuffer content, String encoding) {
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod(url);
// 设置url连接超时
client.getHttpConnectionManager().getParams()
.setConnectionTimeout(timeOut);
// 设置读取数据超时
client.getHttpConnectionManager().getParams().setSoTimeout(timeOut); // 这两行解决 too many open files问题 by jdzhan
client.getParams().setBooleanParameter("http.protocol.expect-continue",
false);
// 解决Httpclient远程请求所造成Socket没有释放 by jdzhan
method.addRequestHeader("Connection", "close"); method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,
encoding); try {
client.executeMethod(method);
String respString = method.getResponseBodyAsString();
content.append(respString); } catch (ConnectTimeoutException e) {
errorString = "Connect Timeout:" + url;
return false;
} catch (SocketTimeoutException e) {
errorString = "Socket Timeout:" + url;
return false;
} catch (IOException e) {
errorString = e.toString();
return false;
} finally {
method.releaseConnection();
} return true;
}

Eclipse初次java开发问题总结-3的更多相关文章

  1. Eclipse初次java开发问题总结-4-Maven使用问题汇总

    Non-resolvable parent POM [INFO] Scanning for projects... [ERROR] The build could not read 1 project ...

  2. Eclipse初次java开发问题总结-2

    今天对之前写的servlet程序做了个简单的性能测试发现了一些问题,经过解决这些问题没有再重现,有些问题自己确切知道原因,有的则不太确定. 1.配置文件读取问题 项目中使用.properties作为配 ...

  3. Jdk1.7+eclipse搭建Java开发环境

    Jdk1.7+eclipse搭建Java开发环境 1.    下载jdk1.7 http://www.oracle.com/technetwork/java/javase/downloads/jdk7 ...

  4. Eclipse For Java开发环境部署

    Eclipse For Java开发环境部署 1.准备工作 jdk安装包 jdk官网下载 Eclipse安装包 Eclipse官网下载 Eclipse下载时选择图中所示的国内镜像地址下载 下载后的文件 ...

  5. Eclipse的Java开发中jar导入后无法使用包内class的解决方案

    请注意, 本方法只对于自己的包有效, 如果你的类内部互相调用, 此方法会失效, 需要每个类文件都进行一次CTRL+SHIFT+O进行包的导入. 如上图的一个结构, algs4.jar和stdlib.j ...

  6. 不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧

    Jerry和SAP成都研究院一些新同事聊天时,谈到ABAP和SAP GUI这个话题.很多新同事在加入SAP成都之前,是做Java和C++开发的,习惯了Eclipse/IntelliJ IDEA/Vis ...

  7. 每个Java开发人员都应该知道的10个基本工具

    大家好,我们已经在2019年的第9个月,我相信你们所有人已经在2019年学到了什么,以及如何实现这些目标.我一直在写一系列文章,为你提供一些关于你可以学习和改进的想法,以便在2019年成为一个更好的. ...

  8. Eclipse for Python开发环境部署

    Eclipse for Python开发环境部署 工欲善其事,必先利其器. 对开发人员来说,顺手的开发工具必定事半功倍.自学编程的小白不知道该选择那个开发工具,Eclipse作为一个功能强大且开源免费 ...

  9. Java开发环境的搭建以及使用eclipse从头一步步创建java项目

    一.java 开发环境的搭建 这里主要说的是在windows 环境下怎么配置环境. 1.首先安装JDK java的sdk简称JDK ,去其官方网站下载最近的JDK即可..http://www.orac ...

随机推荐

  1. 在vue-cli搭建的项目中在后台mock接口中支持req.body和req.cookies

    在<vue-cli搭建的项目中增加后台mock接口>中实现了后台mock,但是前端post的t数据都要在mock的后台接口中使用req的接收数据事件获取http协议body中的数据. re ...

  2. 2015-06学习总结——c++

    在工作快三年的时候,突然想到我需要凝练下自身的知识体系.从大一开始接触c++,差不多快8年了.想想过去走过的学习之路,很简单,也很曲折. 经历了从一无所知——入门——应用——修修补补的过程,到现在可以 ...

  3. django创建应用

    创建应用--在一个项目中可以创建多个应用,每个应用进行一种业务处理 打开CMD,进入project(目录名)的目录下,输入命令创建名为myApp的app: python manage.py start ...

  4. Android开发(八)——Android组件

    参考: [1] Android开发教程:理解Intent和Intent Filter.http://liuzhichao.com/p/506.html

  5. C#学习笔记(27)——委托排序(1)

    说明(2017-11-20 17:21:35): 1. 感觉难点都在冒泡排序上..貌似之前跳过去了没学啊!冒泡排序的精髓就在于,两两比较,最大的排到最后一位,再把前面的重新两两比较,把最大的排到倒数第 ...

  6. bzoj1103【POI2007】大都市meg

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1544  Solved: 776 [Submit][St ...

  7. JQUERY根据值将input控件选中!

    <select>: $('#country').find("option[value = " + data.country + "]").attr( ...

  8. 定位被选中的select

    <script> var countryId = "{$user['country']}"; $("select[@name='country'] optio ...

  9. mac上使用zsh配置环境变量

    Mac配置环境变量的地方 一./etc/profile (建议不修改这个文件 ) 全局(公有)配置,不管是哪个用户,登录时都会读取该文件. 二./etc/bashrc (一般在这个文件中添加系统级环境 ...

  10. Virtual DOM 虚拟DOM的理解(转)

    作者:戴嘉华 转载请注明出处并保留原文链接( #13 )和作者信息. 目录: 1 前言 2 对前端应用状态管理思考 3 Virtual DOM 算法 4 算法实现 4.1 步骤一:用JS对象模拟DOM ...