2012-03-20 2 views
10

JavaEE 웹 애플리케이션 내에서 들어오는 메시지를 도착 순서대로 엄격하게 처리해야합니다. 웹 포트 컨테이너 (Tomcat 6)는 http 포트에 도착할 때 메시지 순서를 유지한다고 가정합니다.엄격한 순서의 메시지 동시 처리

내게 두통을 일으키는 원인은 내가이 메시지를 내부적으로 처리하는 방식입니다. 작업 부하를 개선하기 위해 ThreadPool에 각 메시지의 처리를 추가합니다. XML 구문 분석, 때로는 외부 웹 서비스를 사용하여 데이터를 풍부하게합니다. 처리가 끝나면 메시지의 Java 표현을 복잡한 스트림 처리 엔진 esper.codehaus.org으로 푸시합니다. 이는 스레드 세이프입니다. 여기서, 입구 순서가 가장 높은 필요 조건 인 현상의 임계 값을 초과하는 경우 다른 패턴을 확인합니다.

도착한 시간에받은 우선 순위 ID가있는 모든 처리 된 메시지를 PriorityQueue에 삽입하는 아이디어가있었습니다 (각 서블릿에서 각 메시지에 대해 증가되는 위치). 문제는 다음과 같습니다.

에스페에 삽입하기 위해 큐에서 요소를 폴링하는 스레드 (가장 낮은 ID는 큐의 머리입니다)가 누락 된 항목을 확인하지 않으므로 ID를 건너 뛸 수 있습니다. 나는 그림이 더 밖으로 작동 추측 : 의도 한대로 단계는

enter image description here

(1)에 (4) 모든 작동합니다. 그러나 단계 (5)에서 QueuePoller는 엘리먼트 6을 검색하지만 엘리먼트 4는 검색하지 않는다 (단계 (6)에서 나중에 삽입 됨). 메시지 순서는 다음과 같습니다. 2; 삼; 6; 4.

내가 시도한 것은 큐의 머리를 폴링하여 ID의 엄격한 순서를 따르도록 구현을 변경하는 것이 었습니다. 의미, 다음 ID의 요소가 아직 큐에 삽입되어 있지 않으면 거기까지 배리어를 기다리십시오. 이것은 처음 10 분 동안 작동하는 것처럼 보였으 나 대기열에 삽입되지 않은 요소로 인해 중단되었습니다.

과거에 비슷한 문제가있는 사람 중에 나에게 어떤 힌트가 있습니까?

+0

대기열 항목이 서버에 도착하자마자 작성하는 것이 더 좋을 수 있습니다. 대기열 항목을 대기열에서 순서대로 가져오고 처리가 완료된 후에 만 ​​대기열 항목을 가져올 수 있습니다. –

+0

이해가 안되는 점은 출력 대기열의 요소 순서가 입력 대기열의 순서와 일치해야한다면 순서가 잘못된 순서로 처리된다는 것입니다. 즉, QueuePoller가 6 이전에 4를 가질 필요가 있다면 4보다 먼저 6을해야하는 이유는 무엇입니까? – aib

+0

나는 그 두 가지에 대해 생각했지만 비슷한 결과를 가져올 것이라고 생각합니다. 처리가 끝났음을 나타내는 플래그를 사용한다고 가정합니다. 처리 중에 문제가 발생하면 동일한 문제가 발생할 수 있습니다 (서버 시간 초과 등이 요소가 삽입되지 않은 문제 임). 따라서 표시기 플래그는 절대로 true로 설정되지 않습니다. – matthes

답변

3

체크 아웃 Disruptor - 엄격한 순서에 고성능 큐 (최초 입력 - 최초의 봉사는)

+0

젠장, 나는 그것을 말하려고했다 :-) – dty

+0

OP 상황은 항목이 순서가 잘못된 스레드로 들어오고 항목의 키에 의해 주어진 순서대로 처리해야하는 것 같다. 어떻게 방해물이 이것을 해결할 것인가? –

+0

링크를 제공해 주셔서 감사합니다. 문제가 해결되면 꼭 확인하고 다시 신고 해 드리겠습니다. 빨리 읽은 후에도 누락 된 요소를 기다리는 것을 해결하지 못하는 것 같습니다. 그렇지 않으면 충분히 읽지 못했습니다. – matthes

0

클래스 라이브러리는 몇 가지 유용한 사전 정의 된 구성과 함께 유연한 스레드 풀 구현을 제공합니다. Executors에서 정적 팩토리 메서드 중 하나를 호출하여 스레드 풀을 만들 수 있습니다.

필요에 따라 Executors.newSingleThreadExecutor()가 가장 적합하다고 생각합니다. 단일 스레드 실행 프로그램은 작업을 처리 할 단일 작업자 스레드를 생성하고 예기치 않게 종료되면이를 대체합니다. 작업은 작업 대기열 (FIFO, LIFO, 우선 순위)에 의해 부과 된 순서에 따라 순차적으로 처리되도록 보장됩니다.

+0

그러나 성능의 비용으로 실제로 주문 제약 조건을 충족시킵니다. –

+0

위의 설명에서 언급했듯이, 다른 모든 것이 작동하지 않으면 이것이 실현 될 마지막 해결책입니다. 메시지 처리는 많은 경우에 매우 비쌉니다. – matthes

0

귀하의 문제와 다이어그램에 대한 필요성 (즉, +1)에서 알 수 있듯이 우선 순위 대기열은 원하는 것에 적합하지 않습니다. 대기열이 사용할 수 없게 될 때까지 대기하는 대신 6 개를 대기열에 넣기 때문에 대기열이 완벽하게 기쁘기 때문입니다.

동기화 컨테이너를 굴릴 때가되었습니다.

+0

나는 이것을 막기를 바랐다. (많은 일을하는 것처럼 보인다 :) – matthes

+0

우선 순위 큐를 악용하는 것보다 더 많이해서는 안된다 : D – aib

1

들어오는 요청에 대한 자리 표시자를 즉시 ​​처리 대기열에 추가 할 수 있습니다. 자리 표시자는 스레드 풀에 의해 백그라운드에서 사전 처리되지만 주 처리는 전처리가 완료 될 때까지 대기합니다. 내가 생각한 구조는 Future입니다.