HttpClient: Метод HttpGet не выполнен: служба HTTP / 1.0 503 недоступна - PullRequest
0 голосов
/ 29 февраля 2012

спасибо за чтение.

Такая досадная проблема возникла у меня, я заслуживаю того, чтобы кто-то мне помог. Я использую httpcomponent (новую версию прежнего httpclient) в java, чтобы открыть некоторые URL-адреса и записки содержимого. И многопоточный режим используется для повышения производительности.

Так что это проблема:

1.потоки разделяют HttpClient

1) Defination

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; 
    }

, а затем примерно через 600 циклов из 10 потоков происходит еще одно дерьмо:

**Exception in thread "Thread-11" java.lang.OutOfMemoryError: Java heap space**

Исключение возникает в result = EntityUtils.toString (entity); line

Так что, действительно, нужна помощь.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 29 февраля 2012

503 означает, что сервис недоступен, поэтому сервис недоступен.Теперь это может быть связано с тем, что вы на самом деле обращаетесь к одной и той же службе снова и снова и в результате выдает ошибку или отказывает вам в обслуживании из-за такой нагрузки.память, потому что вы использовали все это.Либо ваша программа имеет утечку памяти, либо вы должны увеличить размер кучи с помощью -Xmx256m, -Xmx512m, -Xmx1G и т. Д. В SO есть множество ответов на эти вопросы.

1 голос
/ 29 февраля 2012

Ответ, данный Гийомом, звучит для меня совершенно разумно.Что касается вашей второй проблемы, причина для OutOfMemoryError довольно проста.DefaultHttpClient объекты очень дороги и, создавая новый экземпляр для каждого запроса, вы намного быстрее истощаете свои системные ресурсы.Кроме того, обычно EntityUtils#toString следует избегать для чего-либо, кроме простых тестов.Следует использовать ответные сообщения HTTP как поток контента без буферизации всего тела ответа в памяти.

...