ЦП завис от 95% до 100% для автономного сервера Jetty

Я использую Jetty для запуска основного класса в качестве службы. Ниже фрагмент кода для демонстрации проблемы.

    Server server = new Server(8080);
    ResourceHandler resource_handler = new ResourceHandler();
    resource_handler.setDirectoriesListed(true);
    resource_handler.setWelcomeFiles(new String[] {"index.html"});
    resource_handler.setResourceBase(".");
    HandlerList handlers = new HandlerList();
    handlers.setHandlers(new Handler[] {resource_handler, new DefaultHandler()});
    server.setHandler(handlers);
    server.start();
    server.join();

Я запускаю это приложение из eclipse на машине Windows с 2 процессорами.

После того, как я запускаю это приложение, я запускаю программу ниже на другой машине. Код ниже просто порождает 100 одновременных потоков и выполняет простой HTTP-запрос для получения страницы index.html.

ExecutorService service = Executors.newFixedThreadPool(100);
for (int i = 0; i < 10000; i++) {
  service.execute(new Runnable() {
    public void run() {
      try {
        long startTime = System.nanoTime();
        URL url = new URL("http://localhost:8080");
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setRequestMethod("GET");
        long endTime = System.nanoTime();
        System.out.println(conn.getResponseMessage() + ":" + ((endTime - startTime)/1000000) + " (ms)");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  });
}
service.shutdown();

Когда я запускаю эту программу, ЦП сервера сразу достигает 100% (для обоих ядер).

Я попытался изменить maxThreads, acceptorThreads, параметры размера буфера, как это предлагается в https://wiki.eclipse.org/Jetty/Howto/High_Load.

Но даже тогда процессор по-прежнему зависает между 95-100 при высокой нагрузке.

Итак, вопрос в том, есть ли какая-либо конфигурация, которую мне не хватает, чтобы минимизировать нагрузку на ЦП? Или это ожидаемо и может быть исправлено только путем добавления дополнительных ЦП или кластеризации служб?

Спасибо за вашу помощь.


person user1401472    schedule 06.01.2015    source источник


Ответы (1)


Вы заявляете, что запускаете часть ExecutorService на другом компьютере, но URL-адрес — http://localhost:8080. Это недопустимо в нагрузочном тестировании.

Некоторые советы:

  • Не располагайте клиентскую нагрузку и серверную нагрузку на одном компьютере (не обманывайте и не пытайтесь загрузить две разные виртуальные машины на одной физической машине)
  • Используйте несколько клиентских машин, а не только одну (когда разработчики Jetty проверяют характеристики нагрузки, мы используем соотношение клиентских машин к серверным как минимум 10:1).
  • Не тестируйте с обратной связью, виртуальными сетевыми интерфейсами, локальным хостом и т. д. Используйте реальный сетевой интерфейс.
  • Не тестируйте нереалистичные сценарии нагрузки. Реальное использование вашего сервера будет заключаться в большинстве конвейерных соединений HTTP/1.1 с несколькими запросами на физическое соединение. Некоторые в быстрых сетях, некоторые в медленных сетях, некоторые даже в ненадежных сетях (например, мобильных)
  • Если вы должны использовать HttpURLConnection, узнайте, как он управляет своей HTTP-версией и соединениями (например, keep-alive или http/1.1 close), и убедитесь, что вы прочитали содержимое тела ответа, закрыли потоки и отключить() соединение.

Наконец, убедитесь, что тестируете нагрузку реалистично.

person Joakim Erdfelt    schedule 06.01.2015
comment
Спасибо за ваш подробный ответ. Это имеет мало зацепок для меня. Да, в коде это указано как localhost, но когда я скопировал его на другую машину, я изменил его. - person user1401472; 08.01.2015