java - HttpClient:HttpGet 方法失败: HTTP/1.0 503 服务不可用

标签 java multithreading httpclient out-of-memory apache-httpcomponents

感谢您的阅读。

我遇到了这么烦人的问题,我值得有人帮助我。 我在java中使用httpcomponent(前httpclient的新版本)来打开一些url和剪贴内容。并且使用multihtread来提高性能。

这就是问题所在:

1.线程共享一个HttpClient

1)定义

private static final ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager();
private static HttpHost proxy = new HttpHost("127.0.0.1",8086,"http");
private static DefaultHttpClient http = new DefaultHttpClient(cm);

2)在我的初始函数中

cm.setMaxTotal(100);
http.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

3)然后是我的线程函数

public static String getUrl(String url, String Chareset)
    {
        HttpGet get = new HttpGet(url);//uri
        get.setHeader("Content-Type", "text/html");
        get.setHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.0; .NET CLR 1.1.4322; .NET CLR 2.0.50215;)");
        get.setHeader("Accept-Charset", Chareset+";q=0.7,*;q=0.7");//"utf-8;q=0.7,*;q=0.7");
    get.getParams().setParameter("http.socket.timeout",new Integer(CONNECTION_TIMEOUT));//20000

        String result = "";
        try {
            HttpResponse response = http.execute(get);
        if (response.getStatusLine().getStatusCode() != 200){//statusCode != HttpStatus.SC_OK) {
                System.err.println("HttpGet Method failed: "
                        + response.getStatusLine());//httpGet.getStatusLine()
        }
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            result = EntityUtils.toString(entity);
            EntityUtils.consume(entity);
            entity = null;
        }
    } catch(java.net.SocketException ee)
    {
            ee.printStackTrace();
            Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ee);
    }
        catch (IOException e) {
            //throw new Exception(e);
            Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, e);//TODO Debug
    } finally {
        get.abort();//releaseConnection();//TODO http.getConnectionManager().shutdown();?
        get = null;
    }
        return result; 
    }

4)然后我创建了 10 个线程来调用 getUrl() 函数,但是在大约 1000 次循环之后,发生了糟糕的情况:

**HttpGet Method failed: HTTP/1.0 503 Service Unavailable**

但是我用IE和代理打开该url,打开成功。所以这意味着我的代理没有问题。

那么出了什么问题?

2.然后我将httpclient的创建更改为getUrl()函数,这样线程就不会共享HttpClient,如下所示:

public static String getUrl(String url, String Chareset)
    {
        HttpGet get = new HttpGet(url);//uri
        get.setHeader("Content-Type", "text/html");
        get.setHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.0; .NET CLR 1.1.4322; .NET CLR 2.0.50215;)");
        get.setHeader("Accept-Charset", Chareset+";q=0.7,*;q=0.7");//"utf-8;q=0.7,*;q=0.7");
    get.getParams().setParameter("http.socket.timeout",new Integer(CONNECTION_TIMEOUT));//20000

        DefaultHttpClient http = new DefaultHttpClient(cm);//threads dont't share it
        http.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

        String result = "";
        try {
            HttpResponse response = http.execute(get);
        if (response.getStatusLine().getStatusCode() != 200){//statusCode != HttpStatus.SC_OK) {
                System.err.println("HttpGet Method failed: "
                        + response.getStatusLine());//httpGet.getStatusLine()
        }
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            result = EntityUtils.toString(entity);
            EntityUtils.consume(entity);
            entity = null;
        }
    } catch(java.net.SocketException ee)
    {
            ee.printStackTrace();
            Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ee);
    }
        catch (IOException e) {
            //throw new Exception(e);
            Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, e);//TODO Debug
    } finally {
        get.abort();//releaseConnection();//TODO http.getConnectionManager().shutdown();?
        get = null;
                http = null;//clean almost all the resources
    }
        return result; 
    }

然后在 10 个线程的大约 600 个循环之后,又发生了另一件事:

**线程“Thread-11”中出现异常 java.lang.OutOfMemoryError:Java 堆空间**

result = EntityUtils.toString(entity); 行发生异常

所以,真的需要一些帮助。

谢谢!

最佳答案

503表示服务不可用,因此服务已关闭。现在可能是因为您实际上一遍又一遍地访问相同的服务,并最终出现错误或由于这种负载而拒绝您的服务。

第二个错误非常明显:没有更多的内存,因为你已经用完了它。要么你的程序正在泄漏内存,要么你应该使用 -Xmx256m、-Xmx512m、-Xmx1G 等增加堆大小......对于这些问题有大量的答案。

关于java - HttpClient:HttpGet 方法失败: HTTP/1.0 503 服务不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9501228/

相关文章:

java - 如何使用java套接字将文件发送到Web浏览器?

java - 比较两个 BufferedImages 之间像素值的最快方法?

multithreading - JDBC:我可以在多线程应用程序中共享连接并享受良好的交易吗?

multithreading - Await.result还是一个简单的电话?

Android - httpclient 作为后台服务

java jdbc gui应用程序-需要允许用户输入

java - 在 TextView 的背景中,在 fragment 中的每个图像上绘制圆圈

java - 强制方法调用 null 变量以抛出 NullPointerException

java - Android 编程 HtmlUnit

java - 获取 http 响应 PHP 和 ANDROID