The first thing to realize is that applications must be designed to eliminate message affinities in order to scale horizontally. There's a limit to how much the messaging transport can be expected to do to overcome the application's design constraints. Processing which alters message delivery routes, sequence or destination based on message payload contents is properly a job for an ESB rather than a transport. The optimal solution is to redesign the application with an architecture appropriate for horizontal scaling.
That said, one way to do this is to use message groups. The application instance looking for a new group should ignore any messages in which the JMSXGroupID
is not 1
. The applications sending messages must be prepared to set the group ID and sequence numbers accordingly.
Another way to accomplish this is by intercept-and-dispatch. A program reads the main queue looking for new instances of an ID. When it sees a new ID, it moves that one message to a separate dispatch queue. The consuming application instances all read the dispatch queue looking for work. Since the IDs in this queue are guaranteed to be unique, each Id is assigned to a specific app instance. The app then opens the primary queue using a selector for the ID to be processed. Producer applications must set the ID as a message property or in the Correlation ID field to make the selection possible but they do not need to manage groups.