Похоже, сервлет не работает в многопоточном режиме. - PullRequest
2 голосов
/ 06 мая 2010

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

Сервлет вызывает программу командной строки, выполнение которой занимает около 20 секунд, а затем возвращает результат пользователю через JSON. Проблема в том, что если я делаю более 2 одновременных запросов, сервлет блокируется до тех пор, пока не будет выполнен один из предыдущих запросов.

Пример этого можно увидеть ниже - «Я в» - это вершина сервлета, а список результатов - после того, как сервлет выполнен. Все запросы были сделаны одновременно, но вы можете ясно видеть, что они не обрабатываются одновременно. Какие настройки мне нужно изменить в tomcat, чтобы все запросы обрабатывались одновременно?

Im in 

Im in 

FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
Im in

FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
Im in

FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
Im in

FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
Im in

FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
Im in

FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
Im in

FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE

Ответы [ 4 ]

1 голос
/ 06 мая 2010

Проблема в вашем тесте клиент . Запускает запросы синхронно. Он должен запускать запросы асинхронно, тогда сервлет сможет сделать то же самое:)

Примерно такой же вопрос был задан 4 дня назад, я отправил ответ с примером кода, как должен выглядеть тестовый клиент: Запросы сервлета выполняются последовательно без видимой причины в Glassfish v3 . Вы также можете найти это полезным.

1 голос
/ 06 мая 2010

По умолчанию запросы к сервлетам обрабатываются одновременно. Там нет настройки, которая включает / отключает это поведение. Это подтверждается JavaDoc для HttpServlet :

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

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

Конечно, даже если вы не реализуете SingleThreadModel, вы можете сделать любой сервлет однопоточным, используя (возможно, неуместную) синхронизацию, например,

class MyServlet extends HttpServlet {

  private void Object sharedObject = new Object()

  protected synchronized void doGet(HttpServletRequest req, HttpServletResponse resp) {
    // method logic goes here
  }

  protected void doPost(HttpServletRequest req, HttpServletResponse resp) {

    synchronized(sharedObject) {
      // method logic goes here
    }

  }

  protected void doPut(HttpServletRequest req, HttpServletResponse resp) {

    synchronized(this) {
      // method logic goes here
    }
  }
}

В приведенном выше примере только один поток может одновременно выполнять один и тот же метод запроса, хотя возможно (например) для одного потока выполнить doPost(), в то время как другой выполняет doGet().

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

0 голосов
/ 30 июля 2011

Тот же запрос к тому же серверу будет отправлен, когда вы запустите свое приложение на Tomcat (а не через Eclipse в режиме отладки).

Простой тестовый пример может быть выполнен: сделайте простой doGet, который сделает следующее:

PrintWriter printWriter = response.getWriter();
printWriter.append("doGet: Hello from testServlet! doing some thread check :)");
try{Thread.sleep(15*1000);}catch(Exception e){}
printWriter.close();

теперь запустите веб-браузер и запустите этот сервлет несколько раз, и вы увидите, что все они возвращаются одновременно (+ -). если сервлет не был нарезан, вы ожидаете, что первый вернется через 15 секунд, второй через 30 секунд и так далее ...

0 голосов
/ 06 мая 2010

Убедитесь, что в ваших запросах используются разные HTTP-соединения, и проверьте конфигурацию tomcat, если она разрешает более 1 потока (по умолчанию это разрешено, поэтому, если вы ее не изменили, все должно быть в порядке).

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