zoukankan      html  css  js  c++  java
  • HttpClient的 java.net.SocketException: Too many open files

    今天在维护一个老项目的时候发现,错误:

    java.net.SocketException: Too many open files
    	at java.net.Socket.createImpl(Socket.java:460)
    	at java.net.Socket.getImpl(Socket.java:520)
    	at java.net.Socket.bind(Socket.java:644)
    	at sun.security.ssl.BaseSSLSocketImpl.bind(BaseSSLSocketImpl.java:124)
    	at sun.security.ssl.SSLSocketImpl.bind(SSLSocketImpl.java:65)
    	at sun.security.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:468)
    	at sun.security.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:153)
    	at org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory.createSocket(SSLProtocolSocketFactory.java:82)
    	at org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory.createSocket(SSLProtocolSocketFactory.java:127)
    	at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
    	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)
    

      

    大致意思是,资源未释放。

    代码用的是httpClient,在finally中也关比了资源

     HttpClient client = new HttpClient();
    try{
       PostMethod postMethod = new PostMethod(url);
        ......
       // 执行postMethod
       int statusCode = client.executeMethod(postMethod);
    }cache(Exception e){
    
    }finally{
       if (postMethod != null) {
                    postMethod.releaseConnection();
                    postMethod = null;
                }
    }
    

      

    后来找度娘了解下:

    HttpClient在method.releaseConnection()后并没有把链接关闭,这个方法只是将链接返回给connection manager。
    

      

    所以,我的:postMethod.releaseConnection(); 并没有把链接关闭掉。

    如果使用HttpClient client = new HttpClient()实例化一个HttpClient connection manager默认实现是使用SimpleHttpConnectionManager。SimpleHttpConnectionManager有个构造函数如下 

    /** 
     * The connection manager created with this constructor will try to keep the  
     * connection open (alive) between consecutive requests if the alwaysClose  
     * parameter is set to <tt>false</tt>. Otherwise the connection manager will  
     * always close connections upon release. 
     *  
     * @param alwaysClose if set <tt>true</tt>, the connection manager will always 
     *    close connections upon release. 
     */  
    public SimpleHttpConnectionManager(boolean alwaysClose) {  
        super();  
        this.alwaysClose = alwaysClose;  
    }
    

      

    那么在finally中,就需要关闭他:

     finally {
                if (postMethod != null) {
                    postMethod.releaseConnection();
                    postMethod = null;
                }
                if (client != null) {
                    ((SimpleHttpConnectionManager) client.getHttpConnectionManager()).shutdown();
                    client = null;
                }
            }
    

      

    同时还搜索到了这个2个参数:

    client = new HttpClient();
     //添加关闭连接优化Too many open files异常
    
     client.getParams().setBooleanParameter( "http.protocol.expect-continue" , false ); 
    
    //请求头信息中添加关闭连接优化Too many open files异常
    
    method.addRequestHeader("Connection", "close");
    

      

    搜索了一些文档,没有发现对这两个参数细致的解释,只能不求甚解了。测试后也确实没有文件过多的异常了

    大致可以这样写:

          HttpClient client = new HttpClient();
          //增加的
          client.getParams().setBooleanParameter("http.protocol.expect-continue", false);
    
            //超时时间
             client.setTimeout(90 * 1000);        
            MethodResult response = null;
            PostMethod postMethod = null;
            try {
                postMethod = new PostMethod(url);
                postMethod.setRequestHeader("Content-Type", "application/json;charset=utf-8");
               .......
        
               //增加的
                postMethod.addRequestHeader("Connection", "close");
    
                // 执行postMethod
                int statusCode = client.executeMethod(postMethod);
                 ......
            } catch (HttpException e) {
                logger.error("发生致命的异常,可能是协议不对或者返回的内容有问题", e);
                e.printStackTrace();
                response.setBody("-201");
            } catch (IOException e) {
                logger.error("发生网络异常", e);
                e.printStackTrace();
                response.setBody("-200");
            } finally {
                if (postMethod != null) {
                    postMethod.releaseConnection();
                    postMethod = null;
                }
                //增加的
                if (client != null) {
                    ((SimpleHttpConnectionManager) client.getHttpConnectionManager()).shutdown();
                    client = null;
                }
            }
    

      

  • 相关阅读:
    day10 基本数据类型(下)
    day09 作业
    day09 基本数据类型(中)
    day08 作业
    day8 for循环+基本数据类型(上)
    Python正课109 —— 前端 进阶8
    Python正课108 —— 前端 进阶7
    Python正课107 —— 前端 进阶6
    Python正课106 —— 前端 进阶 5
    Python正课105 —— 前端 进阶4
  • 原文地址:https://www.cnblogs.com/achengmu/p/15180410.html
Copyright © 2011-2022 走看看