2014-03-13 3 views
1

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

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

Однако, хотя конфигурация tomcat установила maxthreads более чем на 200, а также 32 ГБ памяти, была назначена каждый раз, когда одновременно запускается только 7-8 потоков. Что не так? Или многопоточность не является лучшей практикой для многозадачности? Пожалуйста помоги.

Дополнение (14 марта 2014 года) Спасибо за ваш совет. Поэтому мой вопрос может быть более конкретным: 1. Может ли ThreadPoolExecutor улучшить производительность? 2. Может ли NIO улучшить производительность?

Вот исходный код:

String[] listFiles = folder.list(); 
for(int i=0; i<listFiles.length; i++) { 
    synchronized(globalHashMap) { 
    MyTask myTask = new MyTask(listFiles[i]); 
    globalHashMap.put(listFiles[i], myTask); 
    myTask.start(); 
    } 
} 

MyTask { 
    String myFile; 
    Thread myThread; 
    public MyTask(String file) { 
     myFile = file; 
    } 
    public void start() { 
     myThread = new Thread(new Runnable() { 
      do { 
      readCnt = bufferedInputStream.read(bytesArray, 1024, 1); 
      ... 
      } while(not end); 

      postProcessFunction(); 

      synchronized(globalHashMap) { 
       globalHashMap.remove(myFile); 
       globalHashMap.notifyAll(); 
      } 
     } 
     myThread.start(); 
    } 
} 
+2

Многопоточность может помочь вам, если вы используете его правильно. Я бы рекомендовал использовать «ExecutorService» вместо ручного создания ваших потоков. Также учтите, что вы не должны запускать столько потоков. –

+0

Если ваши файлы находятся в одной папке, дисковый ввод-вывод, скорее всего, станет узким местом, я сомневаюсь, что больше потоков, попавших на один и тот же жесткий диск, ускорит работу. – wallenborn

+0

Спасибо за ваш совет. Поэтому мой вопрос может быть более конкретным: 1. Может ли ThreadPoolExecutor повысить производительность? 2. Может ли NIO повысить производительность? –

ответ

1

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

0

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

Для решения вашей проблемы лучшим способом является использование jms. Фоновая задача отправит сообщение в jms broker для обработки каждого файла, найденного на диске. Брокер Jms может обрабатывать сообщения многопоточно и очень эффективно и будет контролировать все многопоточность для вас.

+0

Создание нескольких потоков на сервере приложений не является плохой практикой. Это не рекомендуется, если вы не знаете, что делаете. –

+0

Как насчет использования ExecutorService и Future? –

3

Установка maxThreads в Tomcat не означает макс. # из потоков, которые JVM может иметь. У Tomcat нет контроля над этим. Он определяет макс. # рабочий темы Tomcat сам создаст для обслуживания входящих HTTP-запросов. Ваш Java-код может по-прежнему создавать любые потоки, которые ему нужны.

Что касается того, почему вы получаете только 7 - 8 потоков, мне нужно будет увидеть код, чтобы знать наверняка. Сколько файлов находится в этом каталоге?

Я не уверен, какой анализ вы сделали, но я часто слышу «многопоточность», как консервированное решение для быстрого приготовления, и это очень опасный способ решения проблем. Threading предназначен для решения очень специфического набора проблем. Это должно быть последнее средство. Особенно в веб-приложении. Веб-контейнеры используют несколько загрузчиков классов для развертывания и развертывания и переустановки приложений «на лету». Нитки создают кошмар для обслуживания и часто препятствуют правильной очистке загрузчика классов.

Я действительно видел случаи, когда многопоточность маскирует проблему. Когда я впервые присоединился к своей нынешней компании, в настоящее время предпринимаются усилия для многопоточного процесса, который развертывает сценарии SQL в отношении наших баз данных для применения исправлений ошибок. Жалоба заключалась в том, что процесс был слишком медленным, поэтому решение, конечно же, состояло в том, чтобы параллельно выполнять несколько БД через многопоточность. Недавно я обнаружил, что процесс выполнения скриптов запускает инструкцию SQL (для GRANT) в конце каждого скрипта по каждой базе данных, которая занимает 2 минуты. Это утверждение редко бывает необходимо.Если бы этот процесс был правильно профилирован для начала, моя рекомендация заключалась бы в том, чтобы удалить ненужный код, который бы отбросил процесс с 2-3 часов до < 10 минут. Теперь мы застряли, сохраняя беспорядок кода управления потоками.

Итак, теперь мой вопрос к вам, вы профилировали свой код? Как отметил @wallenborn, дисковый ввод-вывод может быть узким местом. В вашем коде также могут быть оптимизации.

+0

Есть более 1000 файлов. Каждый файл представляет собой обычный текст с 5000 строк, каждая строка меньше 100 символов. После загрузки файла для файла выполняется вычисление 15000. Каждый раз он может обрабатывать около 50 файлов, но занимает очень много времени. В статусе Tomcat используется только 8 потоков. Так странно. –

+0

«В статусе Tomcat используется только 8 потоков». - Что такое статус Tomcat? Как вы это измеряете? – Brandon

+0

8 потоков в http-8080 в состоянии сервера tomcat. В настоящий момент нет посещений. –

Смежные вопросы