메시지 처리 노드 및 구문 분석기는 멀티인스턴스, 멀티스레드 환경에서 작동해야 합니다. 다수의 구문 요소를 포함하는 다수의 노드 오브젝트 또는 구문 분석기 오브젝트가 있을 수 있으며, 이러한 오브젝트의 메소드를 실행하는 다수의 스레드가 있을 수 있습니다. Message Broker는 메시지 플로우를 통해 메시지를 수신하고 처리하는 스레드만 메시지 오브젝트 및 여기에 속하는 모든 오브젝트를 사용하도록 설계됩니다.
메시지 플로우 처리 노드의 인스턴스는 해당 노드가 정의된 메시지 플로우를 서비스하는 모든 스레드에 의해 공유되고 사용됩니다. 구문 분석기의 경우, 구문 분석기의 인스턴스는 단일 메시지 플로우 스레드에 의해서만 사용됩니다.
사용자 정의 확장은 이 모델을 준수해야 하며 여러 스레드에 걸친 액세스를 일련화하기 위한 세미포어를 필요로 하는 전역 데이터 또는 자원을 사용하지 않아야 합니다. 그러한 일련화는 성능 저하를 초래할 수 있습니다.
사용자 정의 확장 구현 기능은 재실행 가능(reentrant)해야 하며, 이들이 호출하는 기능도 재실행 가능(reentrant)해야 합니다. 모든 사용자 정의 확장 유틸리티 기능이 전부 재실행 가능(reentrant)해야 합니다.
사용자 정의 확장은 필요한 경우 추가 스레드를 생성(spawn)할 수 있으나, 구현 기능 완료 시 동일한 스레드가 브로커에 제어를 리턴해야 합니다. 그러지 않을 경우에는 브로커의 무결성이 손상되고 예상치 못한 결과가 발생합니다.
다음 메시지 플로우 예는 사용자 고유의 사용자 정의 노드를 설계 및 구현할 때 알아야 할 몇 가지 스레드 고려사항을 이해하는 데 도움이 됩니다. 사용자 정의 입력 노드의 예를 고려합니다.
스레드 세트에서 실행되도록 메시지 플로우를 구성할 수 있습니다. 이는 메시지 플로우에 있는 입력 노드 수와 메시지 플로우의 추가 인스턴스 등록 정보 값으로 결정됩니다. 이 두 요소는 메시지 플로우가 사용할 수 있는 스레드 풀의 최대 용량을 판별합니다. 따라서 메시지 플로우에서 단일 스레드 실행을 지시하는 특별한 처리 시 요구사항이 있는 경우 사용자가 이를 확인해야 합니다.
추가 인스턴스 등록 정보를 사용하여 브로커가 별도의 스레드에서 메시지 플로우의 추가 사본을 시작할 수 있게 하는 것이 입력 큐에 병목현상이 발생하지 않도록 하는 가장 효과적인 방법입니다. 그러나 별도의 스레드를 작성하면 메시지 큐에 있는 메시지가 병렬로 처리될 수 있으므로, 메시지 처리 순서가 중요하지 않을 때만 이 등록 정보를 사용해야 합니다.
스레드는 입력 노드 구성 및 조작의 결과로서 작성됩니다. 스레드는 스레드 풀에서 활성 또는 비활동 상태로 유지되며, 비활동 스레드는 입력 노드에 의해 브로커되거나 브로커가 종료될 때까지 풀에 남아 있습니다.
아래 그림은 메시지 플로우에서의 스레드 할당을 보여줍니다.
메시지 플로우에서의 스레드 할당
처음에 스레드 1이 요구되어(A) 메시지를 기다립니다. 메시지가 도착하면(B), 스레드 1이 메시지를 전달하고 스레드 2를 디스패치합니다. 스레드 2가 즉시 메시지를 수신하여(C) 전달하고 스레드 3을 디스패치하면, 스레드 3이 메시지를 기다립니다(D). 스레드 1이 완료되어(E) 스레드 풀로 리턴됩니다. 그런 다음 스레드 3이 메시지를 수신하고(F), 스레드 1을 디스패치한 후 메시지를 전달합니다. 이제 스레드 1이 메시지가 큐에 도착하기를 기다립니다(G).
H가 표시된 지점에 주의해야 합니다. 메시지 플로우의 이 인스턴스에서 스레드 1은 메시지를 수신하나, 이 시점에서 다른 모든 스레드가 활성 상태에 있으므로 디스패치를 수행할 수 없습니다. 메시지가 전달됩니다.
이 메시지가 전달된 후에는, 스레드 2가 완료되고(I) 큐에서 새 메시지를 수신하여 이 새 메시지를 전달합니다. 그런 다음 스레드 3이 완료되어(J) 풀로 리턴됩니다. 그런 다음 스레드 2도 완료됩니다(K). 스레드 1이 완료될 때(L), 이 스레드는 디스패치를 수행하지 않았으므로 큐에 메시지가 없더라도 스레드 풀로 리턴할 수 없으며, 대신 큐에 메시지가 도착할 때까지 기다립니다.