2013-10-06 1 views
5

Tomcat 8의 JSR-356 WebSocket 지원을 사용하여 현재 작업중인 응용 프로그램을 구동하고 있습니다. 지금까지는 모든 메시지가 단일 스레드에서 처리되는 것처럼 보입니다. 이 배경의 추론과 웹 소켓이 이렇게 구현 된 이유를 이해하는 동안 (코드에서 ExecutorService를 만들지 않고) 들어오는 메시지를 처리하기 위해 ExecutorService을 사용하는 방법이 있습니까?Tomcat 8 JSR 356 WebSocket 스레딩

실제 메시지의 표준 스레드 기반 처리를 허용하면서 (1 개의 또는 몇 개의) 네트워크 선택기 스레드를 (확장 된 연결된 클라이언트를 지원하기 위해) 확장 할 수 있습니다. 클라이언트 용으로 처리됨).

특별히 변경할 수있는 사항은 없습니다.

답변

13

스레딩 모델은 사용중인 커넥터에 따라 다릅니다. 확장 성을 위해 NIO (기본값) 또는 APR/네이티브 (8.0.0-RC3 현재 버그)를 사용하려고합니다. NIO는 현재로서는 유일한 선택입니다. APR/기본 문제는 곧 수정되어야합니다 (이 질문을 보았을 때 나는 그 작업을하고있었습니다).

NIO는받은 메시지를 처리하기 위해 선택기와 스레드 풀을 사용합니다. 선택기가 데이터를 사용할 수 있음을 감지하면이를 처리하기 위해 스레드를 실행 프로그램을 통해 스레드 풀에서 스레드로 전달합니다. 그 처리는 데이터가 내부적으로 버퍼링되게 할 수 있으며, 애플리케이션은 부분 메시지를 통지 받고, 애플리케이션은 완전한 메시지 또는 이들의 조합을 통지 받는다. 응용 프로그램에 대한 알림은 들어오는 데이터를 처리하는 동일한 스레드에 의해 처리됩니다.

여러 클라이언트에서 여러 메시지를받은 경우 해당 메시지를 처리하기 위해 여러 스레드가 전달됩니다.

JSR 356 API에는 응용 프로그램이 응용 프로그램이 새 메시지를 구현하지 않고 새 메시지를 통보받은 경우 ExecutorService를 통해 메시지 또는 부분 메시지를 처리하도록 선택할 수있는 기능이 없습니다. 전체 메시지 만 처리하는 응용 프로그램에서는 비교적 간단해야합니다. 응용 프로그램이 부분 메시지를 처리하는 경우 훨씬 더 어려워집니다.

APR/네이티브 (한 번 고정)는 NIO와 같은 방식으로 작동합니다. BIO는 (JSR356 API가 비 블로킹을 나타내는 경우에도) 항상 블로킹 IO를 사용하며 처리 할 데이터가있는 연결된 클라이언트 당 하나의 스레드가 아니라 연결된 클라이언트 당 하나의 스레드를 필요로합니다.

+0

그래, 들어오는 데이터를 처리하기 위해 스레드 풀을 사용한다고 말하는 것입니까? 클라이언트 당 최대 단일 스레드가 있습니까? –

+0

테스트 할 때 두 번째 메시지가 처음 처리를 기다리고있는 것처럼 보였기 때문에 묻습니다. 그러나 우리는 같은 세션에서 보낸 것입니다 (어쩌면 그렇게 된 것일 수도 있습니다). 사이드 노트 : 훌륭한 대답 –

+3

클라이언트 당 처리 데이터에 할당 된 쓰레드는 하나만 존재합니다. 클라이언트가 여러 메시지를 보내는 경우 동일한 스레드에 의해 순차적으로 처리됩니다. 스레드가 첫 번째 메시지를 끝내면 읽을 데이터가 더 있는지 살펴볼 것입니다. 있을 경우 읽습니다. 그렇지 않은 경우 소켓은 더 많은 데이터가 도착할 때까지 선택기/폴러로 돌아갑니다. 데이터는 이렇게 처리해야합니다. 더 많은 스레드를위한 범위가있는 곳에서는 일단 메시지 (또는 부분 메시지)가 응용 프로그램에 전달 될 준비가되면 새로운 스레드에서 수행 될 수 있습니다 (그러나 그렇지 않습니다). –