Ре-архитектура веб-службы Java с интенсивным вводом-выводом с использованием пулов потоков и BlockingQueue - PullRequest
0 голосов
/ 14 января 2019

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

Каким сервисом занимается?

Это веб-служба, которая просто принимает файл и передает его на удаленный сервер sftp по сети (через Интернет, а не внутри корпоративной сети). Есть 2 сайта sftp. Таким образом, служба решает, к какому серверу отправлять метаданные, отправленные в самом запросе. Также периодически выполняется 2 задания, которые опрашивают по временной задержке 5 минут на этих 2 sftp-сайтах и ​​извлекают zip-файлы, если таковые имеются.

Что делает работа: Job по очереди вытягивает все доступные почтовые индексы в локальную папку. Затем начинается обработка каждого почтового индекса (с помощью цикла по коллекции почтовых индексов). Сначала он извлекает zip, а затем берет 1 файл PDF и отправляет его в другой веб-сервис (скажем, сервис 1 ) в сети компании. Затем он берет один XML-файл, анализирует его и извлекает из него определенные данные, а затем передает эти данные другой службе (например, службе 2 ).

Что я планирую сделать? Это слишком много работы для одной работы. Я планирую разделить его -> Job будет просто извлекать zip-файлы в локальную папку и помещать имена в BlockingQueue, что приведет к запуску другой работы, и будет выполняться обработка, то есть извлечение zip может обрабатываться параллельно с извлечением zip с удаленного sftp-сервера. Теперь мой запрос заключается в том, что и извлечение zip из удаленного в локальный режим, и обработка zip в локальном режиме на самом деле являются операциями ввода-вывода, но , так как первый - это ввод-вывод по сети, а другой локальный файловый ввод-вывод считает, что используемый канал / шина данных отличается . Так что, если я распараллелю их, это улучшит производительность. Мне нужно сделать это, потому что в будущем число молний будет увеличиваться, скажем, до 1000 молний за один раз, что очень медленно с током. реализация.

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

1) потянув молнию с пульта и

2) локальная обработка почтовых индексов

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

Имеет ли смысл такая перестройка? Что еще можно сделать?

1 Ответ

0 голосов
/ 14 января 2019

Я бы определил количество исполнителей пула потоков на основе типа активности:

  • Один для задач с интенсивным использованием процессора, размером Runtime.getRuntime().availableProcessors(),
  • Один для заданий, связанных с дисковым вводом / выводом, небольшого размера (1..3). HDD лучше всего работают в последовательном режиме. Для SSD вы можете попытаться увеличить размер пула, но в любом случае используйте интенсивную буферизацию (1 МБ +) при параллельном вводе / выводе диска,
  • Один для преимущественно заданий, связанных с сетевым вводом-выводом (4..20, в зависимости от пропускной способности сети и расстояния передачи).

Затем разделите процесс на подзадачи в зависимости от характера задачи. По завершении каждая задача будет передавать свои результаты новой задаче в соответствующем пуле.

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

...