Можно ли открыть несколько подключений к нескольким сайтам, используя только одну ветку? - PullRequest
0 голосов
/ 29 сентября 2011

Обновление

Я уже использую FixedThreadPool. Что происходит, так это то, что каждый поток открывает одно соединение для одного сайта. Я хочу сделать что-то асинхронное.

  1. Отправить запрос на сервер
  2. Переходите к следующему запросу без необходимости ждать завершения первого запроса
  3. Когда запрос был установлен, сделайте что-нибудь, сообщив другому потоку, что соединение установлено и готово к загрузке.

Я думаю, что это ускорит выполнение, потому что будет использовать меньше потоков для открытия того же или большего количества соединений, что и текущая производительность.

В текущем способе каждый поток ожидает время без работы в ожидании установления соединения. Таким образом, он всегда будет работать.


Вопрос

Я хочу знать, есть ли способ открыть соединение с несколькими сайтами только с одним потоком.

Это потому, что я делаю веб-сканер, я уже создал поток, чтобы открыть соединение, но после определенного количества потоков это не поможет, потому что совместное использование процессора значительно увеличится.

Я хочу, чтобы это ускорило количество загруженных страниц. Возможно ли это сделать? Как?

Этот код открывает соединение и выполняет некоторую обработку. Он выполняется потоками, которые открывают соединение

/*
 * Open connection to a server
 */
boolean openConnection(Link link) throws Exception {
    //set the connection paramenters
    HttpURLConnection conn = (HttpURLConnection) new URL(link.getOriginalURL().getURL()).openConnection();
    conn.setRequestProperty("User-Agent", ROBOT_NAME);
    conn.setInstanceFollowRedirects(true);
    conn.setConnectTimeout(READ_TIMEOUT);
    conn.setReadTimeout(READ_TIMEOUT);
    link.setConnection(conn);
    //open the connection
    conn.connect();        
    //check the server answer
    if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
        return false;
    }
    //analyse the URL of the redirected URL
    urlAnalyzer.fillURL(link.getRedirectedURL(), getRedirectedURL(link.getConnection()));
    return true;
}

Выполняет открытие соединений, каждое в одном потоке

/*
 * Start the execution of the connection openers     
 */
private void executeConnectionOpeners() {
    LOGGER.info("Starting connection openners.");
    /* Execution */
    NameThreadFactory ntf = new NameThreadFactory("Connection Opener");
    crawlerOpenerExecutor = Executors.newFixedThreadPool(nOpeners, ntf);
    for (int i = 0; i < nOpeners; i++) {
        crawlerOpenerExecutor.submit(new ConnectionOpener(this));
    }
    /* End of execution */
    LOGGER.info(nOpeners + " connection openers created and running.");
}

Ответы [ 3 ]

3 голосов
/ 29 сентября 2011

Выборка веб-страниц не является особенно трудоемкой работой: вы будете тратить почти все свое время на ожидание сети, если вы не получаете много маленьких страниц из очень быстрых локальных соединений.

Конечно, вы должны посмотреть, сколько потоков на самом деле стоит использовать, с помощью бенчмаркинга - вы, вероятно, захотите иметь фиксированный набор потоков, работающих в общей очереди производителя / потребителя.(Вы не хотите создавать подлинный новый поток для каждого запроса.)

Теперь должно быть возможно использовать только очень небольшое количество потоков, если вы можете выполнять выборку асинхронно (потенциальнос NIO), но я бы лично проверил, действительно ли подход "отдельных потоков" максимизирует ваш ЦП первым.Вероятно, это сделает код намного более простым, чем использование асинхронности, и, если узким местом действительно является сеть, то в итоге вы получите более сложный в обслуживании код для небольшой (если вообще) выгоды.

1 голос
/ 30 сентября 2011

Проверьте и понравится ли вам Java 7 AsynchronousSocketChannel.По сути, вы отправляете запрос на чтение, и когда байты становятся доступны, он вызывает ваш обратный вызов.Конечно, обратный вызов должен быть вызван в каком-то потоке;у вас есть несколько вариантов настройки политики потоков.

0 голосов
/ 30 сентября 2011

Я использовал xlightweb для аналогичной цели, то есть асинхронный HTTP .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...