Сколько потоков на соединение через веб-сокет использует Tyrus?

Я пытаюсь понять модель потоковой передачи для подключения к веб-сокету Tyrus. Использует ли Tyrus один поток для каждого соединения через веб-сокет? Есть ли какой-то механизм объединения потоков?

Я попытался найти документ, описывающий внутреннюю реализацию Tyrus или любую реализацию веб-сокета для Java о том, как работает модель потоков, но я не смог найти ни одного.

Любая информация о том, как работает модель потоков для поддержки соединений через веб-сокеты, полезна.

Я пытаюсь оптимизировать свой сервер, чтобы он мог поддерживать тысячи подключений к веб-сокетам. Прямо сейчас, имея всего 1000 подключений к веб-сокетам, JVM использует ~ 1800 потоков!

Обновление 1:

Я использую Tyrus 1.9 на Tomcat 8.

Сервер завершает около 500 подключений через веб-сокет, а также инициирует 500 подключений через веб-сокет к другому серверу. Итак, сейчас у нас на сервере около 1000 подключений через веб-сокеты.

Одна вещь, которую я заметил, это проблема с TYRUS-275, которая, я думаю, связана с моим случаем. Похоже, что клиент Tyrus по умолчанию создает 3 потока на каждое соединение через веб-сокет. В моем случае у меня около 500 соединений, поэтому у меня должно быть около 1500 потоков только для исходящих соединений через веб-сокет.

Также похоже, что если я включу общий контейнер в Tyrus, то смогу извлечь выгоду из использования пулов потоков SELECTOR и WORKER.

client.getProperties().put(ClientProperties.SHARED_CONTAINER, true);
client.getProperties().put(GrizzlyClientProperties.SELECTOR_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(3));
client.getProperties().put(GrizzlyClientProperties.WORKER_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(10));

Теперь мне интересно, как оптимизировать пулы потоков? Сколько потоков SELECTOR и WORKER мне нужно иметь для 500 подключений к веб-сокетам? Есть ли формула?

Обновление 2:

Когда я подключаюсь к JVM, я вижу следующие потоки (перечислены только интересные):

- 24   x WebSocketServer-localhost-ROOT-xxxx [mostly parked]
- 1    x WebSocket background processing [mostly asleep]
- 10   x tyrus-1-thread-xx [mostly parked]
- 10   x tyrus-2-thread-xx [mostly parked]
- 1    x Tomcat JDBC Pool Cleaner [waiting]
- 1    x Signal Dispatcher [all running]
- 9    x nioEventLoopGroup-x-x [all running]
- 1    x main [all running]
- 177  x Keep-Alive-Timer [sleeping]
- 1    x java-sdk-htttp-connection-reaper [sleeping]
- 1    x http-apr-8080-Sendfile [waiting]
- 1    x http-apr-8080-Poller [running]
- 200  x http-apr-8080-exec-xxx [mostly parked with running slices]
- 1    x http-apr-8080-AsyncTimeout [sleeping]
- 1    x http-apr-8080-Acceptor-0 [running]
- ~630 x Grizzly(1) [mostly parked]
- ~634 x Grizzly(1) SelectorRunner [mostly running]
- ~635 x Grizzly(2) [moslty parked]

Я предполагаю, что потоки Grizzly - это те, которые клиент Tyrus создает для каждого веб-сокета (кстати, я думаю, что не считал потоки Grizzly тщательно. Я думаю, что счет должен быть одинаковым для всех трех из них). Один селектор два рабочих, верно?

Я думаю, что http-apr-8080-exec-xxx — это потоки, созданные tomcat. Заботятся ли эти потоки о входящих соединениях через веб-сокет? Меня больше интересуют следующие темы:

  • WebSocketServer-localhost-ROOT-xxxx
  • Тайрус-х-нить-хх
  • nioEventLoopGroup-х-х
  • Keep-Alive-таймер
  • http-апрель-8080-exec-xxx

Кто-нибудь знает, что делает каждый набор потоков? Есть ли какой-нибудь документ, объясняющий это?

Также похоже, что мой Tomcat настроен на использование разъема APR. Мне было интересно, что использование NIO или NIO2 может быть лучшей идеей в этой ситуации ?!


person kaptan    schedule 10.07.2015    source источник
comment
вам определенно следует использовать ClientProperties.SHARED_CONTAINER .. и вам действительно не нужно устанавливать пулы потоков в этом случае, поскольку гризли настроит их автоматически. (634 селекторных бегунка - это слишком много, с вашей текущей нагрузкой может справиться ‹5).   -  person Pavel Bucek    schedule 14.07.2015


Ответы (1)


Это зависит от вашего окружения. Tyrus (сервер!) Сам по себе не должен создавать новые потоки, он просто использует те контейнеры (Glassfish, WebLogic, ... (Grizzly при работе в автономном режиме сервера)).

Кроме того, это зависит от того, что вы делаете в конечных точках. Если вы постоянно получаете/отправляете сообщения в каждом соединении, то для этого должен быть поток. В противном случае, если вы просто подключитесь и ничего не сделаете, Tyrus сам ничего не должен делать, если только вы не используете функцию сердцебиения или что-то подобное.

Итак, я не могу сказать, почему ваша JVM использует так много потоков (кстати, они все активны? Я сомневаюсь в этом ..) - вам нужно предоставить гораздо больше информации, если вы хотите решить подобные проблемы. Вы можете начать с предоставления кода (лучше всего исполняемого), чтобы мы могли воспроизвести то, что вы видите; не стесняйтесь переместить это на [email protected], это, вероятно, закончится разговором, который не вписывается в модель «SO вопрос/ответ».

person Pavel Bucek    schedule 12.07.2015
comment
Я добавил больше информации. Я ценю, если вы можете взглянуть. - person kaptan; 14.07.2015