Decoupling services with message-oriented middleware

So far in this chapter, we've discussed direct communication between client and server or between services. Another important way to implement asynchronous communication is through the use of middleware, or more specifically, by implementing asynchronous communication through the use of queues. To start with, let's take a classic publisher-consumer problem, where service A is responsible for generating some information, which is to be consumed by another service, B. Though the communication can be synchronous as well, where we can configure our application in a way that the communication is deemed completed when a successful acknowledgment is received by calling the service, this kind of communication is best suited to asynchronous communication. 

We can implement two major types of communications patterns using messaging: point-to-point and publisher-subscriber. In point-to-point communication, as the name suggests, we have two endpoints. One would serve as publisher, sending messages to the listener point, known as a consumer.

The following diagram shows a simple point-to-point communication:

A simple example is an order-management service and an inventory-management service in an e-commerce system. Whenever an order is executed, the order-management service would add a message to the queue that the order was successfully executed. The message is read by the inventory service, which in turns updates inventory. The advantage of using a queue-based approach is that it removes any dependency between the two services.

The order-management service doesn't need be aware of the inventory service. All it is aware of is a middleware queue that it needs to add the message to; what happens with the message is not its responsibility. So, even if an inventory management service is down or broken, the order management will work fine without any disruption. The messages will be available in the queue, and when the inventory service is fixed, it will consume all the messages.

This example highlights a couple of important aspects of this kind of communication. We can see very clearly that order-management system will keep on working without even knowing whether inventory is being updated properly. It is important to understand our use case: do we actually want this level of decoupling? This brings another aspect, which is that even if the inventory service were down for some time, we have actually not missed any updates. When the service was up, it consumed all the messages and data was eventually corrected. 

If we were just logging the order details for reporting purposes, we could have used queue-based communication without giving it a second thought. But, if our use case can result in incorrect data in the system, we should be carefully accessing our tolerance of the delay in receiving the data.

So far, we've looked into cases where we had one publisher and one consumer. Say we have a case where more than one services wants to take an action on a message. In the preceding example, we have both log-management and inventory-management systems, which are interested in an order-completion event. In such cases, we use an approach known as publisher-subscriber or pub-sub. In this approach, instead of publishing to a queue, we publish to a specific topic  for example, order-completion can be a topic. Multiple publishers can publish to a topic and multiple subscribers can listen to a topic.

The following diagram shows a pub-sub architecture:

In our example case, the order-management service would be publishing a message to the order completed, whenever an order is executed successfully, and services, such as logging service and inventory-management service, listen on this topic. Whenever a new message is published, these services consume the message and take appropriate action.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.223.190