What is Publisher and Subscriber pattern
Publisher and Subscriber (PUB/SUB) is a messaging pattern where 3 different components are involved:
The first one is in charge of sending (Publisher) a particular message.
The second one, the Subscriber, is the one who receives the message.
The first and second components do not know about the existence of one another.
The third component, called message broker, which is known by both the publisher and subscribers is in charge of filtering and delivering incoming messages accordingly.
We can imagine a subscriber as a guy who is listening to a radio station. The publisher is the radio station, and the radio waves is the broker.
As soon as the radio station starts to transmit music to a specific frequency, whoever is listening to that frequency will be able to listen to what is being transmitted by them.
What is important to understand is that publishers do not program the message to be sent directly to specific(s) receivers or subscribers. They publish the messages without any knowledge of any subscribers there may be.
How Publishers delivery messages ?
As I said, Publishers are not programmed to send a specific message to a specific receiver.
Messages are published into channels by publishers. Subscribers subscribe their interest into one or more channels in order to receive messages that are of (their) interest to them.
We have to bear in mind that publishers and subscribers are not aware of the existence of each other(s).
This is a main feature that leads to a high level of scalability.
Moreover, Subscribes receive only a subset of the total messages published due to a selecting process called filtering.
There are two different filtering methods:
topic-based: messages are published to channels identified by topics or logical names. As a result, all the subscribes to a topic will receive all messages published to the topic they subscribe.
content-based: messages are only delivered to a subscribe if the content of the messages match a given definition or constraints previously defined by the subscriber.
However, some systems support both methods or a combination of the two.
Usually the message broker performs the filtering of the messages as well as all the publishing and subscribing operations needed to deliver(y) messages. In fact, the broker performs a store and forward function to route messages from publishers to subscribers. Moreover, the broker can order by priority all messages in a queue before delivering them to the subscribers.
Advantages of Publisher and Subscriber:
It goes without saying the one advantage of PUB/SUB is the decoupling of the three components in 3 dimensions:
Space decoupling: Publishers and subscribers do not need to know each other. Moreover Publishers do not need to know how many subscribers would be interested in a given topic.
Time decoupling: Publishers and subscribers do not need to run at the same time.
Synchronisation decoupling: Operations on both components are independent and agnostic and they act without blocking each other
Scalability: PUB/SUB allows systems to scale better than the traditional client-server and it has proven its benefits when used in system with a medium-large amount of traffic.
Research has found that under high-volume enterprise load (a data center with a large amount of services sharing messages), the Publisher and Subscriber pattern could suffer of low performances.
Common internet protocol, such as RSS and Atom use the PUB/SUB design pattern to delivery message.
Smart Solution: From my point of view, when you think how several components of an application could share information, you would like to have a clean and simple way to achieve that goal. Using Publisher and Subscriber usually leads to a clean design and to a performant solution.
Easy Testing: All things considered,It’s pretty easy to debug and monitor a Pub/Sub system.
On the one hand decoupling of the 3 main components is the greatest advantage of Pub/Sub but on the other hand is also its biggest disadvantage.
In fact, the message broker could unpredictable fails delivering a message and due to the fact that Publishers are completely agnostic about the existing of subscribes and vice versa, there is no way to know if a message has been delivered to someone or not. Of course we could develop a custom solution to monitor each messages but everyone should wisely decide when apply a Pub/Sub and when prefer another solution, I guess.
As I said before, as the number of subscribers and publishers increase, the whole system may be not so stable and some messages could be lost in the air,under a huge demand of data.
Security: Actually, there is no security system to prevent a malicious user to break into the system and inject wrong messages.
The PUB/SUB pattern is similar to, often confused with, one of the most common and important design pattern, the Observer Pattern.
One of the most complete definition of the Observer pattern is provided in the book Design Patterns: Elements of Reusable Object-Oriented Software:
"One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves."
Basically, the Observer Pattern is a design pattern where an object maintains a list of objects depending on it. Let’s call the object subject and the list of objects observers.
The object automatically notifies each observers when there are changes in the state of a subject.
If we want to remove a particular observer from the list, the subject can do it and as a result, that observer will never be notified of any changes.
Differences between The Observer and Publish/Subscribes Pattern.
The Observer pattern requires that the observer must subscribe his interest to receive topic notifications.
The Publish/Subscribe pattern uses a message broker to trigger events and delivery messages accordingly.
In the Observer pattern the observers are aware of the subject whereas, in the PUB/SUB publishers and subscribes do not need to know each other but the only need to care about what channel to use to exchange messages.
Pub/Sub allows to dynamically register for a specific topic rather than having a static list of subscribers.
The Observer pattern is mostly implemented in a synchronous way.
The PUB/SUB pattern is mostly implemented in an asynchronous way using a message queue as message broker.
Personally speaking, I usually use the Observer pattern when the subscribes are in the same process and I need to maintain consistency between related objects, without building classes tightly coupled.
On the contrary, I prefer a PUB/SUB implementation when I need to send interprocess notifications to notify other objects without making assumptions regarding those objects.
In general, both the Observer and Publish/Subscribes design patterns are a good way to think deeply about the relationships between different parts of an application.
In my opinion, this leads to a good and strong application design which means our application will be perform better.
As a result of its inner loosing coupled architecture, Pub/Sub is extremely useful when we are designing and developing a microservices applications.