Chapter 4. Application design
4.5 Messaging application design
4.5.1 Application design in general
This section contains general messaging guidelines related to message producers, consumers, and the underlying infrastructure.
Message types
Based on the intent, messages can be classified as one of the following: Command messages that enable procedures call semantics to be executed
on another system
Document messages enabling a messaging system to transport a document or information
A command message in fact is a simple regular message containing a command together with its parameters. Command messages are usually sent point-to-point so that each command will be consumed and executed once.
A message does not necessarily need to trigger some functionality on another system. Sometimes it just needs to pass information. For this reason there are document messages. A document message can be seen as one parameter of a command message or the result of a command message, with no intention of triggering a specific function on the other system. Document messages are not only used in point-to-point but also in publish-subscribe scenarios in case a number of recipients need to be addressed.
A request-reply scenario is a sample where both message types are used. The request represents a command message, triggering some remote functionality. The reply only transmits the result of the functionality and therefore tends to be a document message.
Message expiration
Sometimes guaranteed delivery without time constraint makes no sense. For that reason an expiration duration can be attached to each message to indicate after what amount of time a message becomes unusable and therefore should just be discarded.
Purging old messages from queues is an important consideration in the design of a messaging-based application. Not doing so will lead to poor performance and maintenance issues as more and more messages are jamming the queues. In the event that discarding messages by expiration is not possible, another approach needs to be applied, like adding application logic to a client for monitoring the queues and handling old messages. For this reason messaging systems provide browse functionality for queues in their API to support the scanning of messages without reading them out of the queue.
Message persistency
Another design consideration is whether messages need to be persistent or non-persistent. Non-persistent messages do not survive process failure, but because of their nature they can be processed much faster by the messaging infrastructure and are less resource consuming. The decision to use persistent or non-persistent messages is generally governed by the business requirements.
Request-reply logging
Both the service consumer and service provider should maintain a request-reply log containing the message ID, the request and reply message, as well as related key information like the request and reply timestamps and the reply address. In addition, the system should be designed such that each request belongs to a unique message ID and can thus be identified using the message ID. In other words, two messages containing the same message ID reflect the same request.
Maintaining a request-reply log is considered a best practice and shows advantages in different areas:
Eases system maintenance
By maintaining a request-reply log we always know the requests a service consumer issued, the requests a provider got, which requests have been
Note: Some messaging systems do not allow users to set the message ID,
but provide their own unique identifier. In such cases the correlation ID should be used for the request identification.
processed, and what the outcome of the processing was. This provides a solid background for debugging purposes and performance measurement. Prevents the execution of the same request more than once
In cases where requests lead to persistent data manipulation we need to make sure that each request is processed only once. However, we need to support resubmit functionality so application logic is required to implement this constraint.
Supports the concept of self-healing systems
The concept of self-healing systems leads to the ability of a system to recover itself from certain failures. By maintaining a request-reply log the service consumer always knows which requests are due and is therefore able to decide whether a specific request should be resubmitted.
Recovery can be needed if, for example, a service consumer crashes during the processing of the reply and the reply message may be lost. To recover and successfully process the reply, the service consumer would need to force the provider to send the reply again. This can be achieved by resubmitting a request using the same message ID.
Figure 4-10 on page 80 shows the activity diagram of a provider’s request handling using an applied request-reply log. A request only gets processed if there is no log entry with the same message ID. If an entry exists, the reply is taken from the log and put on the reply queue. Further processing is skipped, thus guaranteeing consistency between request and reply.
Figure 4-10 Activity diagram of the request handling using a request log