Несколько постов с Httpclient 4.0.3 зависают случайным образом - PullRequest
4 голосов
/ 14 января 2011

позвольте мне объяснить ситуацию.

У меня есть сервлет, перенаправляющий исходящий GET / POST в другой проект в другом домене (какой-то прокси-сервер), чья задача - обрабатывать его и возвращать некоторые вещи (params и gif). Я использую HttpClient 4.0.3 для этого.

При запуске моего приложения отправляется несколько запросов GET / POST, поэтому я однажды настроил ThreadSafeClientConnManager для обработки нескольких потоков.

cm_params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(cm_params, 200);

ConnPerRouteBean connPerRoute = new ConnPerRouteBean();
HttpHost localhost = new HttpHost("localhost");
connPerRoute.setMaxForRoute(new HttpRoute(localhost), 50);

ConnManagerParams.setMaxConnectionsPerRoute(cm_params, connPerRoute);

SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
        new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

cm = new ThreadSafeClientConnManager(cm_params, schemeRegistry);

Затем я создаю новый HttpClient с этими параметрами, которого должно быть достаточно для одновременной обработки нескольких запросов. Конечно, я делаю это на public void service () для каждого GET / POST, но я использую тот же объект Httpclient после того, как я его создал.

httpclient = new DefaultHttpClient(cm, cm_params);

После этого я создаю свой POST и отправляю его через execute с проверкой всех требуемых параметров и такой тройки.

    HttpPost httpPost = new HttpPost(target+tmpString); 

    httpPost.setHeader("Host", request.getHeader("host"));
    httpPost.setHeader("User-Agent", request.getHeader("user-agent"));
    httpPost.setHeader("Accept-Encoding", request.getHeader("accept-encoding"));
    httpPost.setHeader("Accept", request.getHeader("accept"));
    ..etc..

    UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params);
    urlEncodedFormEntity.setContentEncoding(HTTP.UTF_8);
    httpPost.setEntity(urlEncodedFormEntity);

    HttpResponse response = httpclient.execute(httpPost);

Наконец я читаю поток и обрабатываю сущности ...

    OutputStream os = res.getOutputStream();
    InputStream is = response.getEntity().getContent();
    byte[] buf = new byte[1024];
    for(int n;(n=is.read(buf))!=-1;)
    {
        os.write(buf, 0, n);
    }
    // Make sure to close
    is.close();
    os.close();

    // Flush entities just in case
    EntityUtils.consume(urlEncodedFormEntity);
    EntityUtils.consume(response.getEntity());
    urlEncodedFormEntity.getContent().close();
    response.getEntity().getContent().close();

Так что моя проблема в том, что код работает отлично, когда я загружаю свою страницу. Отправлено 4 запроса (1 GET, 3 POST). В основном возвращает несколько параметров и 1 маленький GIF, которые я печатаю на своей странице.

Но как только я начинаю стресс-тестирование моего приложения, I.E. загружая одну и ту же страницу в 4-5 вкладок, мое приложение, кажется, зависает в случайном порядке, когда я выполняю несколько POST одновременно. Я думал, что у меня не возникнет никаких проблем, даже если я использую тот же объект Httpclient , поскольку я правильно объявил свой ThreadSafeClientConnManager (я думаю?), Поэтому он должен обрабатывать несколько потоков.

Кто-нибудь знает, что я делаю не так? Если я загружаю свои вкладки 1 на 1, он не зависает. Просто когда я обновляю более 1 вкладки одновременно.

У кого-нибудь есть подсказка? : S (sry english не мой родной язык ^^;)

Ответы [ 4 ]

3 голосов
/ 18 января 2011

@ Apache Fan, установка этого:

ConnManagerParams.setMaxTotalConnections (cm_params, 200); connPerRoute.setDefaultMaxPerRoute (50);

Сомневаюсь, что у меня может закончиться соединение, я открываю 3-4 вкладку, и она исчерпывается ... может быть, 4 POST на вкладку, чтобы не сложить: S

2 голосов
/ 15 января 2011

Вы можете взглянуть на это из HttpClient API -

ThreadSafeClientConnManager поддерживает максимальный лимит соединений для каждого маршрута и в целом. По умолчанию эта реализация будет создавать не более 2 одновременных подключений на данный маршрут и всего не более 20 подключений. Для многих реальных приложений эти ограничения могут оказаться слишком ограниченными, особенно если они используют HTTP в качестве транспортного протокола для своих служб. Пределы соединения, однако, могут быть скорректированы с использованием параметров HTTP.

Возможно, в вашем приложении не хватает пула, и вам нужно увеличить размер пула.

0 голосов
/ 23 сентября 2016

Я застрял в той же ошибке.Мы заметили, что HttpClient не закрывается.

То, что я сделал, я попробовал метод HttpClientUtils.closeQuietly () на моем неочищенном HttpClient и HttpResponse. Это помогло моей причине и перестало зависать.Вы также можете попробовать и поэкспериментировать с ним.

0 голосов
/ 08 марта 2014

Недавно я пытался добиться этого, но у меня возникла новая проблема, например, когда я впервые отправлял запрос, он отправлял без cookie, но во второй раз httpContext автоматически добавлял cookie, но это стандартный способ отправки, но иногдаЗапрошенный сервер принимает без cookie, так что для этого я использовал INTERCEPTOR.Во второй раз он удаляет автоматически добавленные файлы cookie, после этого он работал нормально. Пожалуйста, используйте этот код перехвата httpClient, указанный ниже:

httpClient.addRequestInterceptor(new HttpRequestInterceptor() {

        @Override
        public void process(HttpRequest request, HttpContext context)
                throws HttpException, IOException {
            LOG.info("***************** Entered My Interceptor ****************************");
            Header[] headers = request.getAllHeaders();
            for (Header eachHeader : headers) {
                LOG.info("Headers -- Name: {}, Value: {} ",
                        eachHeader.getName(), eachHeader.getValue());
            }
            request.removeHeaders("Cookie");
        }
    }); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...