Дизайн для многопоточного клиента REST API

Я работаю над программой, которая получает поисковые запросы по теме, делает вызовы API к API New York Times для получения статей, связанных с этой темой, а затем к API Twitter для получения твитов, в которых упоминаются статьи, и, наконец, обрабатывает результаты и возвращает его обратно.

Я должен сделать это многопоточным. Я думал об использовании ExecutorService с пулом потоков фиксированного размера. Таким образом, каждый входящий поисковый запрос будет обрабатываться отдельным потоком. Я также использую интерфейс Callable для отправки задач. Класс, который реализует Callable, выполняет обработку API (создание и получение запросов/ответов API). Наконец, результат извлекается Future и отображается в качестве вывода. Это происходит для каждого входящего запроса.

Имеет ли это смысл? Или есть лучший способ сделать это?

РЕДАКТИРОВАТЬ: я запускаю это на своей локальной машине, принимающей данные из интерфейса командной строки.


person gofeddy    schedule 28.02.2012    source источник
comment
Какое серверное приложение?   -  person Amir Raminfar    schedule 28.02.2012


Ответы (2)


Если это веб-приложение, оно по умолчанию является многопоточным. Если это не так - вы все равно можете развернуть его в контейнере сервлетов, это было бы полезно. Пул потоков предоставляется базовым контейнером (например, tomcat). Каждый запрос обслуживается отдельным потоком.

Единственное, о чем нужно заботиться:

  • не использовать synchronized
  • очистить все ThreadLocal переменные, которые вы используете
person Bozho    schedule 28.02.2012
comment
Это не веб-приложение. Я запускаю его на своей локальной машине, принимающей данные из CLI. Но я все еще хочу сделать его многопоточным. - person gofeddy; 28.02.2012
comment
Почему бы вам не запустить его в контейнере сервлетов? - person Bozho; 28.02.2012
comment
Думаю, со временем рассмотрю этот вариант. До этого я пытался понять, смогу ли я что-то реализовать с помощью набора функций java.util.concurrent. - person gofeddy; 28.02.2012

Я бы сосредоточился на корректировке рабочего процесса, а затем профилировал, чтобы увидеть, где находятся узкие места, а затем попытался увидеть, где параллелизм ( threading != concurrency или асинхронное выполнение ) может вам помочь. Насыщение вашего ЦП, сети или дискового ввода-вывода несколькими потоками выполнения не ускорит работу и обычно снижает производительность, особенно на процессорах Intel с гиперпоточностью.

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

Многопоточность не волшебным образом означает, что она будет работать быстрее или эффективнее, если задачи по-прежнему сериализованы в рабочем процессе. Напротив, это может даже сделать работу медленнее и менее эффективной, если у вас нет передачи сообщений и асинхронных вещей прямо перед рукой.

Кроме того, если вы используете это на ноутбуке с процессором Core i7, вы получите только 4 реальных потока (4 гиперпотока обычно ухудшают ситуацию в приложениях, привязанных к ЦП) и накладные расходы на попытки сделать что-то из последовательный порядок, а затем их возвращение может не дать вам реальной выгоды и большой сложности. На гораздо большем количестве основных серверов это может быть не так, на ноутбуке многопоточность не принесет вам многого.

«Выполнять параллелизм легко, но правильно делать параллелизм очень сложно!» — перефразируя моего Айкидо-сенсея

person Community    schedule 28.02.2012
comment
Интересно, будет ли использование Node.JS простым асинхронным решением... - person beny23; 28.02.2012
comment
Я думаю, это не имеет большого значения в целом. Я пытался каждый раз отправлять 10-15 запросов с пулами потоков разного размера, но время ответа никогда не показывало никаких улучшений/изменений. Кроме того, прямо сейчас я вижу, что мое использование Futures для получения результатов после отправки задач блокирует это приложение. Я посмотрю на это, чтобы увидеть, смогу ли я сделать его неблокирующим. - person gofeddy; 28.02.2012
comment
@Jarrod Roberson: четыре гиперпотока обычно ухудшают работу приложений, привязанных к ЦП [так в оригинале]... И на ноутбуке многопоточность не даст вам многого [sic ]... Что касается первой цитаты, ссылки приветствуются. Что касается второй цитаты, я неоднократно был свидетелем прямо противоположного: используя схему производитель/потребители для обработки данных, я получаю лучшую пропускную способность при адаптации количества потоков-потребителей к количеству процессоров (уже заметно на старых ноутбуках Core 2 Duo Mac, например). Вы действительно поддерживаете однопоточный производитель/потребитель в наши дни и в эпоху многоядерных процессоров? - person TacticalCoder; 28.02.2012
comment
не защищая однопоточного производителя/потребителя, я говорю, что неправильные попытки бросить потоки на проблемы вызывают больше проблем, которые гораздо сложнее решить. Процессоры Core iX не снижают производительность при высокой нагрузке на ЦП. Пример: компиляция программного обеспечения без использования потоков с гиперпоточностью выполняется быстрее, чем с ними. При настройке i3 threads = 2 или i7 threads = 4 это примерно на 25% быстрее, чем включение всех потоков при компиляции. Но без надлежащего асинхронного/неблокирующего дизайна многопоточность является спорным вопросом, потому что она все равно не будет параллельной. - person ; 28.02.2012
comment
@TacticalCoder, ты споришь сам с собой, я никогда не говорил ничего из того, о чем ты споришь. Но, к вашему сведению, если у меня есть сериализованный процесс и рабочий процесс, использующий более 1 потока, это не будет иметь отрицательного эффекта и никогда не будет иметь положительного эффекта. Компиляция на i7 с потоками = 8 намного медленнее, чем с потоками = 4. Переключение контекста и промахи кеша очень неэффективны, особенно в Windows! - person ; 28.02.2012
comment
@TacticalCoder ваша ошибочная интерпретация threads = 1 обычно снижает производительность вы написали, что я не сделал того, чего не говорил, вырван из контекста, прочитайте для понимания. В контексте я сказал, что 4 потока могут быть быстрее, на 25% или более чем 8 потоков на ЦП с гиперпоточностью с приложением, привязанным к ЦП, насыщение ЦП контекстами 8 потоков может быть плохим, простым и понятным. Вы читаете в нем все, что хотите, но я не говорил ничего из того, что вы интерпретируете, просто и ясно. - person ; 29.02.2012
comment
На всякий случай, если кто-то неправильно истолковал вышесказанное (как и я): не думайте, что, поскольку многопоточное программирование может быть сложным, оно того не стоит, и, конечно же, не думайте, что использование более одного потока замедлит ваше приложение (я все еще думаю, что приведенный выше ответ подразумевает именно то, как он сформулирован). Например, если вы хотите скомпилировать большое программное обеспечение на Core i7, делать это с использованием только одного потока на i7 будет ужасно медленно. Выполнение этого с использованием четырех потоков принесет ускорение на 400%. - person TacticalCoder; 29.02.2012