上篇中提到解决的一个问题是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. SeekBar: 修改SeekBar中进度条的高度

    SeekBar中有两个很特别的属性需要留意下: 1.android:maxHeight和android:minHeight .前者是用来指定进度条最大高度的(此高度并非SeekBar整个控件的高度), ...

  2. [iOS]终极横竖屏切换解决方案

    [iOS]终极横竖屏切换解决方案 大家的项目都是只支持竖屏的吧?大多数朋友(这其中当然也包括博主),都没有做过横屏开发,这次项目刚好有这个需求,因此把横竖屏相关的心得写成一遍文章供诸位参考. 01.综 ...

  3. Asp.Net解析json字符串

    方法一: using LitJson; string json= "{...........}"; JsonData jdData = JsonMapper.ToObject(js ...

  4. Mysql异常问题排查与处理——mysql的DNS反向解析和客户端网卡重启

    中午刚想趴一会,不料锅从天降!!!Mysql连不上了....... 现象如下: 现象1:登录mysql所在服务器,连接MySQL 成功: 现象2:通过客户端远程连接MySQL,返回失败,如下: Ent ...

  5. LeetCode: 【L4】N-Queens 解题报告

    [L4]N-Queens 解题报告 N-Queens Total Accepted: 16418 Total Submissions: 63309 My Submissions The n-queen ...

  6. Orcale11g单机安装与卸载

    前言:本篇主要介绍Oracle11g企业版安装的准备工作,建议使用图形化界面安装,静默安装出现问题较多,初学者不好排查,本篇只给出关键步骤,最后介绍完全删除Orcale方法: Oracle Datab ...

  7. java 多线程 24 : 线程组

    线程组 可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示: 线程组的作用是:可以批量管理线程或线程组对象,有效地对线 ...

  8. 备份Android机上的照片

    [本文出自天外归云的博客园] 一年一度的春节放假开始了,今天收拾柜子发现了一台上大学时候用的android机,里面有几百张当年的回忆. 写了个shell脚本遍历了下照片存放的路径,然后用一个pytho ...

  9. ZooKeeper管理分布式环境中的数据

    Reference: http://www.cnblogs.com/wuxl360/p/5817549.html 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它 ...

  10. java中ThreadExecutor使用注意

    如果使用了submit(Runnable task) 就会出现这种情况,任何的错误信息都出现不了! 这是因为使用submit(Runnable task) 的时候,错误的堆栈信息跑出来的时候会被内部捕 ...