最近接触的sendHttpPostRequest的问题比较多,近期碰到了关于 "java.net.SocketException: Too many open files" 的问题

异常信息如下:

ERROR | 2016-01-12 03:19:36.642 | ERROR | IREAD | [Exception]exception stack info | com.huawei.bme.commons.util.debug.DebugLogImpl.doLog(DebugLogImpl.java:480)
java.net.SocketException: Too many open files
at java.net.Socket.createImpl(Socket.java:397)
at java.net.Socket.getImpl(Socket.java:460)
at java.net.Socket.bind(Socket.java:577)
at sun.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.commons.httpclient.protocol.ReflectionSocketFactory.createSocket(ReflectionSocketFactory.java:139)
at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:125)
at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at com.huawei.iread.duibaintf.duiba.sns.SNSServer.sendPostRequestWithCode(SNSServer.java:296)
at com.huawei.iread.duibaintf.duiba.sns.SNSEngine.sendPostRequestWithCode(SNSEngine.java:92)
at com.huawei.iread.duibaintf.duiba.duibamall.GetDuibaExchangeResultNotifyImpl.getDuibaExchangeResultNotify(GetDuibaExchangeResultNotifyImpl.java:91)

其实也就是因为 sendPostRequestWithCode 和 getDuibaExchangeResultNotify 方法调用了 HttpClient.executeMethod 引起的。


查找linux服务器中open files文件数,发现好多是下面的情况,意思是socket资源泄漏,进程使用的sock未关闭:

COMMAND     PID       USER   FD      TYPE             DEVICE   SIZE/OFF       NODE NAME
java 27185 duiba 100u sock 0,7 0t0 92280355 can't identify protocol
java 27185 duiba 101u sock 0,7 0t0 92282035 can't identify protocol
java 27185 duiba 102u sock 0,7 0t0 92280901 can't identify protocol
java 27185 duiba 103u sock 0,7 0t0 92282036 can't identify protocol
java 27185 duiba 104u sock 0,7 0t0 92280389 can't identify protocol
java 27185 duiba 105u sock 0,7 0t0 92280390 can't identify protocol
java 27185 duiba 106u sock 0,7 0t0 92280391 can't identify protocol
java 27185 duiba 107u sock 0,7 0t0 92280392 can't identify protocol

Java源代码中是这样写的:

try{
httpMethod = new PostMethod(url)
// 设置header信息,传输XML格式的
httpMethod.setRequestHeader(CONTENT_TYPE_NAME, CONTENT_TYPE_VALUE_XML_UTF_8);
httpMethod.setRequestEntity(entity); HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());//使用连接池技术创建
httpClient.executeMethod(httpMethod);
}catch{...}
finally{

if (null != httpMethod)
    {
        httpMethod.releaseConnection();//释放资源
    }

}

从上面看,最后, httpMethod.releaseConnection();//释放资源。实际上,HttpClient建立Socket时 ,post.releaseConnection()并没有真正关闭连接,而是将该连接提交给 MultiThreadedHttpConnectionManager,等待复用。而http的连接是等待timeout才会自动断开的,所以,当用完系统的句柄后,自然会报Too many open files。

所以,应该添加下面的代码进行释放socket:

try{
httpMethod = new PostMethod(url)
// 设置header信息,传输XML格式的
httpMethod.setRequestHeader(CONTENT_TYPE_NAME, CONTENT_TYPE_VALUE_XML_UTF_8);
httpMethod.setRequestEntity(entity);
//请求头信息中添加关闭连接
httpMethod.addRequestHeader("Connection", "close"); HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());//使用连接池技术创建
httpClient.executeMethod(httpMethod);
//连发三次机制
httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false);
}catch{...}
finally{
if (null != httpMethod)
{
httpMethod.releaseConnection();//释放资源
} }

还有一种说法:

linux的文件打开数超过了默认的1024个文件,具体查看linux下面的文件打开最大值的命令ulimit -a,出现信息如下:
core file size          (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 69631
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 69631
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimite
其中open files                      (-n) 1024 默认为1024,
有说解决方法是加大文件打开的最大值,ulimit -n 8192
但是由于Httpclient引起的。当并发访问量过大的时候,这个方法只是治标不治本的。所有还是解决Httpclient远程请求所造成Socket没有释放,使用上面的方法较好。

使用httpclient时候,出现“Too many open files”问题的更多相关文章

  1. 用httpClient的PostMethot频繁发送数据,抛出Too many open files

    在工作过程中,用httpclient去压测一个web api,发现压一小段时间就出现了Too many open files.实际上,HttpClient建立Socket时 ,post.release ...

  2. 用httpclient做压力测试时Too many open files的解决办法

    在工作过程中,用httpclient去压测一个web api,发现压一小段时间就出现了Too many open files.实际上,HttpClient建立Socket时 ,post.release ...

  3. The type javax.ws.rs.core.MediaType cannot be resolved. It is indirectly referenced from required .class files

    看到了http://stackoverflow.com/questions/5547162/eclipse-error-indirectly-referenced-from-required-clas ...

  4. 使用httpclient发送get或post请求

    HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建 ...

  5. 一个C#的与web服务器交互的HttpClient类

    using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Net ...

  6. webclient 和httpclient 应用

    //webclient应用 MyImageServerEntities db = new MyImageServerEntities(); public ActionResult Index() { ...

  7. 【JAVA】通过HttpClient发送HTTP请求的方法

    HttpClient介绍 HttpClient 不是一个浏览器.它是一个客户端的 HTTP 通信实现库.HttpClient的目标是发 送和接收HTTP 报文.HttpClient不会去缓存内容,执行 ...

  8. 重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient

    [源码下载] 重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient 作者:webabcd 介绍重新想象 Windows 8.1 Store ...

  9. HttpClient使用方法(包括POST文件)

    最近在做跨系统的数据交互业务,从.Net的系统提交数据到Java的系统. 简单的表单Get.POST都没问题,但是有个功能是要提交普通文本和文件,试了好多都有问题,最后用HttpClient小折腾了一 ...

随机推荐

  1. java笔试题整理

    exit()是system类的方法,如system.exit(); 如果某个方法是静态的,它的行为就不具有多态性. 类后面没有括号,方法必须要有返回值.如果没有返回值,要写void 构造函数不具有多态 ...

  2. eclipse 利用已有c++代码建工程,并编译执行

    如果你想建一个带Makefile的c++ 工程 1. 新建一个C++空工程,工程类型是makefile project,选择Linux GCC: 2. 将源码连同makefile文件一同作为一个文件系 ...

  3. href="#"会导致location.replace(location.href);脚本不工作

    我们经常这样:<a onclick="xxx" href="#" 其实这不是一个好习惯,当点下这个连接后,主页面的URL后面会加个#号,这样就会导致很多J ...

  4. DBLINK的session无法关闭,报异常!

    ------解决方法-------------------------------------------------------- --ALTER SESSION alter session clo ...

  5. iOS 序列化与反序列化

    开篇 1到底这个序列化有啥作用? 面向对象的程序在运行的时候会创建一个复杂的对象图,经常要以二进制的方法序列化这个对象图,这个过程叫做Archiving. 二进制流可以通过网络或写入文件中(来源于某教 ...

  6. Python+Django+Eclipse 在Windows下快速开发自己的网站

    一.配置开发环境 我的开发环境是:Python3.3.2 + Django1.5.2 + Eclipse 1.安装Python 下载地址:http://www.python.org/getit/ 安装 ...

  7. JavaScript脚本语言基础(一)

    导读: JavaScript代码嵌入HTML文档 JavaScript代码运行方式 第一个实例 JavaScript的三种对话框 定义JavaScript变量 JavaScript运算符和操作符 Ja ...

  8. 每日一九度之 题目1038:Sum of Factorials

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2109 解决:901 题目描述: John von Neumann, b. Dec. 28, 1903, d. Feb. 8, 1957, ...

  9. oracle 树状查询

    做树状查询的时候,oracle有自己的优势,一条sql语句就可以搞定,而mysql这种数据库就只能用递归了... 递归的项目实例: //递归取到栏目路径 public List getTreeList ...

  10. java中几种常见字符集与乱码介绍

    1.  ASCII和Ansi编码 字符内码(charcter code)指的是用来代表字符的内码 .读者在输入和存储文档时都要使用内码,内码分为  单字节内码 -- Single-Byte chara ...