Установите предел очереди через jetty.xml в плагине Jetty 9 Maven

Пул потоков в Jetty по умолчанию реализуется с неограниченной очередью после заполнения пула потоков. Я хотел бы установить ограничение на размер очереди. Существует конструктор для BlockingArrayQueue, который принимает значение maxCapacity, но я не вижу способа вызвать его с помощью jetty.xml. Начиная с Jetty 9, нет установщика для пула потоков в org.eclipse.jetty.server.Server, я могу только получить ссылку на уже созданный пул потоков и изменить его (см. этот ответ). И установщик для поля очереди в QueuedThreadPool выдает UnsupportedOperationException, предлагая использовать внедрение конструктора. Но это невозможно, если я могу только изменить пул потоков, а не установить новый на экземпляре сервера. Попытка определить пул потоков в качестве аргумента конструктора приводит к следующему предупреждению:

2014-09-22 13:15:13.688:ПРЕДУПРЕЖДЕНИЕ:oejx.XmlConfiguration:main: Игнорируется аргумент: | 200501000| 6000| ложь|

Это с плагином Jetty Maven v9.2.2.v20140723. Вот конфигурация в моем pom.xml:

    <configuration>
      <jettyXml>${basedir}/jetty.xml</jettyXml>
      <stopKey>x</stopKey>
      <stopPort>7999</stopPort>
      <requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
        <append>true</append>
      </requestLog>
      <webApp>
        <war>${basedir}/target/app</war>
        <contextPath>/app</contextPath>
      </webApp>
      <scanTargets>
        <scanTarget>${basedir}/src/main/webapp/WEB-INF/</scanTarget>
      </scanTargets>
      <reload>manual</reload>
    </configuration>

person Cameron    schedule 19.09.2014    source источник


Ответы (2)


Обновление: Конструктор сервера — это то, как вы настраиваете пул потоков, к сожалению, вы не можете настроить конструктор сервера из jetty-maven-plugin . Это выходит за рамки плагина jetty-maven.


ThreadPool в Jetty 9 теперь настроен на Конструктор экземпляра Server.

Используя XML, вы можете перенастроить его, это даже задокументирован в самом файле jetty.xml.

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

Вот удобная формула салфетки.

Максимальное количество потоков = (((количество ядер процессора) * 4) * (количество коннекторов)) + (максимальное количество одновременных запросов)

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

Думать, что вам нужно установить верхний предел производительности, — это форма преждевременной оптимизации.

Это правда, что QueuedThreadPool, который использует Jetty, не связан, но он также очищает себя и удаляет потоки из пула с течением времени, позволяя серверу обрабатывать внезапные нагрузки и отключаться, когда нагрузка спадает.

Если вас беспокоит память или другие ресурсы, знайте, что установка Jetty по умолчанию работает нормально даже на Android 2.3 (Gingerbread) (примечание: Jetty 7 с QTP), Android 4.4 (Jetty 9) и Raspberry Pi (Jetty 7 через 9).

Наконец, как установить размер очереди приема.

Настройте свой ServerConnector (обычно находится в etc/jetty-http.xml)

<Set name="acceptQueueSize">40</Set>

Значение по умолчанию — 0 и относится к параметру backlog в ServerSocketChannel.bind(SocketAddress,int) на самых низких уровнях.

person Joakim Erdfelt    schedule 19.09.2014
comment
Спасибо за Ваш ответ. Я рассматривал возможность установки размера очереди на основе этого документа: wiki.eclipse.org/ Jetty/Howto/High_Load, а также при попытке воспроизвести эту ошибку на моей машине разработки: bugs.eclipse.org/bugs/show_bug.cgi?id=444031. В любом случае, что касается фактического обновления пула потоков, я пробовал то, что предлагает jetty.xml, но получаю следующее предупреждение: WARN:oejx.XmlConfiguration:main: Ignored arg: ‹Arg name=threadpool›‹New id=threadpool class=org .eclipse.jetty.util.thread.QueuedThreadPool/›‹/Arg› - person Cameron; 23.09.2014
comment
wiki.eclipse.org предназначен для Jetty 7 и 8, а не для Jetty 9 (как написано в верхней части вики) - person Joakim Erdfelt; 23.09.2014
comment
Единственная причина для этого игнорируемого аргумента заключается в том, что у вас есть что-то, что настраивает сервер до того, как этот xml сможет выполниться. (потребуются подробности о вашем запуске/конфигурации/${jetty.base}, чтобы узнать больше). Но теперь это ПУТЬ выходит за рамки этого раздела комментариев. Задайте свой вопрос в списке рассылки пользователей причала. - person Joakim Erdfelt; 23.09.2014
comment
Спасибо, я проигнорирую информацию в Wiki. Но я думаю, что попытка настроить этот сервер с помощью jetty.xml находится в рамках этого вопроса (в то время как часть «почему» может не быть). Я обновил вопрос, чтобы он был более конкретным для плагина Jetty Maven, поскольку я его использую. Я добавил конфигурационную часть плагина... не уверен, что еще можно рассказать, все остальное готово. - person Cameron; 23.09.2014
comment
Спасибо, обновление ответило на мой вопрос. Похоже, вы не рекомендуете устанавливать ограничение на очередь принятия, но это было рекомендовано в качестве возможного шага в комментарии 20 к bugs.eclipse.org/bugs/show_bug.cgi?id=444031, поэтому я собираюсь попробовать и посмотреть, поможет ли это. - person Cameron; 16.10.2014

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

Я думаю, что это подлинный вопрос, следующий подход.

Поскольку невозможно переопределить размер или тип пула по умолчанию в Jetty Server. Мы написали собственный ServerConnector, где вы можете установить размер очереди или вашего исполнителя, если на то пошло.

jetty.addServerCustomizers((Server server) -> {
    LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue< (maxQueueSize);
    ExecutorService exceutorService =
        new ThreadPoolExecutor(minThreads, maxThreads, 1,
            TimeUnit.HOURS, queue);

    // extract host and port from existing connector...
    String host = "0.0.0.0";
    int port = 1900;
    for (Connector c : server.getConnectors()) {
        if (c instanceof ServerConnector) {
            host = ((ServerConnector) c).getHost();
            port = ((ServerConnector) c).getPort();
        }
    }


    ServerConnector connector = new ServerConnector(server, exceutorService, null, null, -1, -1, new HttpConnectionFactory());
    connector.setHost(host);
    connector.setPort(port);
    server.setConnectors(new Connector[] { connector });
}

Минусы

1) Поскольку Jetty ожидает пул потоков в очереди, когда мы пробовали то же самое, он давал случайные результаты, когда запуск сервера завершался неудачно, несмотря на правильные конфигурации. Поведение было непредсказуемым.

2) Поскольку ExecutorService не реализует Threadpool, плагин сбора метрик для Jetty может работать неправильно.

Этот ответ будет обновляться, когда мы приступим к производству.

person Anshul Sao    schedule 22.01.2017