【Architectural Pattern】Publish/Subscribe Pattern

Posted by 西维蜀黍 on 2021-10-24, Last Modified on 2022-12-10

Definition

In software architecture, publish–subscribe pattern is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers, but instead categorize published messages into classes without knowledge of which subscribers, if any, there may be. Similarly, subscribers express interest in one or more classes and only receive messages that are of interest, without knowledge of which publishers, if any, there are.

Publish–subscribe is a sibling of the message queue paradigm, and is typically one part of a larger message-oriented middleware system. Most messaging systems support both the pub/sub and message queue models in their API, e.g. Java Message Service (JMS).

This pattern provides greater network scalability and a more dynamic network topology, with a resulting decreased flexibility to modify the publisher and the structure of the published data.

Message filtering

In the publish-subscribe model, subscribers typically receive only a subset of the total messages published. The process of selecting messages for reception and processing is called filtering. There are two common forms of filtering:

  • topic-based
  • content-based

Topic-based

In a topic-based system, messages are published to “topics” or named logical channels.

Subscribers in a topic-based system will receive all messages published to the topics to which they subscribe, and all subscribers to a topic will receive the same messages.

The publisher is responsible for defining the classes of messages to which subscribers can subscribe.

Content-based

In a content-based system, messages are only delivered to a subscriber if the attributes or content of those messages matches constraints defined by the subscriber.

The subscriber is responsible for classifying the messages.

Advantages and Disadvantages

Advantages

Loose coupling

Publishers are loosely coupled to subscribers, and need not even know of their existence.

With the topic being the focus, publishers and subscribers are allowed to remain ignorant of system topology. Each can continue to operate normally regardless of the other.

In the traditional tightly coupled client–server paradigm, the client cannot post messages to the server while the server process is not running, nor can the server receive messages unless the client is running.

Many pub/sub systems decouple not only the locations of the publishers and subscribers but also decouple them temporally.

Scalability

Pub/sub provides the opportunity for better scalability than traditional client-server, through parallel operation, message caching, tree-based or network-based routing,

Disadvantages

The most serious problems with pub/sub systems are a side-effect of their main advantage: the decoupling of publisher from subscriber.

Message delivery issues

A pub/sub system must be designed carefully to be able to provide stronger system properties that a particular application might require, such as assured delivery.

Deliver messages only one time

The broker in a pub/sub system may be designed to deliver messages for a specified time, but then stop attempting delivery, whether or not it has received confirmation of successful receipt of the message by all subscribers.

A pub/sub system designed in this way cannot guarantee delivery of messages to any applications that might require such assured delivery.

Tighter coupling of the designs of such a publisher and subscriber pair must be enforced outside of the pub/sub architecture to accomplish such assured delivery (e.g. by requiring the subscriber to publish receipt messages).

Assume that a subscriber is listening

A publisher in a pub/sub system may assume that a subscriber is listening, when in fact it is not.

A factory may utilize a pub/sub system where equipment can publish problems or failures to a subscriber that displays and logs those problems.

If the logger fails (crashes), equipment problem publishers won’t necessarily receive notice of the logger failure, and error messages will not be displayed or recorded by any equipment on the pub/sub system. This is also a design challenge for alternative messaging architectures, such as a client/server system. In a client/server system, when an error logger fails, the system will receive an indication of the error logger (server) failure. However, the client/server system will have to deal with that failure by having redundant logging servers online, or by dynamically spawning fallback logging servers. This adds complexity to the client and server designs, as well as to the client/server architecture as a whole. However, in a pub/sub system, redundant logging subscribers that are exact duplicates of the existing logger can be added to the system to increase logging reliability without any impact to any other equipment on the system. In a pub/sub system, the feature of assured error message logging can be added incrementally, subsequent to implementing the basic functionality of equipment problem message logging.

Publish–Subscribe Pattern and Event driven

The event-driven architecture is a typical example based on publish-subscribe pattern. While message-oriented middleware (MOM) is a typical example based on the event-driven architecture.

An event-driven system typically consists of event emitters (or agents), event consumers (or sinks), and event channels.

Since the publish-subscribe pattern decouples the publishers and subscribers, there is no any coupling (or loose coupling) between event consumers and event emitters. However, there is a significant side-effect: it is hard to debug, modify or monitor an event-driven based program.

Differences Between The Observer And Publish/Subscribe Pattern

观察者模式的核心思想,与发布-订阅模式(Publish/Subscribe Pattern)非常类似的,即通过引入一个 事件通知(Event Notification) 机制将事件两端的对象(事件发生对象和关注该事件发生的对象)实现解耦。

  • 耦合关系不同
    • 在观察者模式中,Subject 松耦合于 Abstract Observer
    • 而发布 - 订阅模式可以看做是观察者模式的一种变种。通过引入 Broker 层,作为 SubjectObserver 之间的中间层,最终 SubjectObserver 之间不存在任何耦合
  • 讨论的上下文所处的粒度不同
    • 观察者模式往往在一个代码实现的上下文去讨论的(Design Pattern),即 programming language specific;
    • 而发布 - 订阅模式既可以在一个代码实现的上下文去讨论(Design Pattern),也可以从架构设计的角度讨论。这时,发布 - 订阅模式更多是一个架构模式(Architectural Pattern)。比如 ** 面向消息的中间件系统(message-oriented middleware system,MOMS)** 则是从架构层面实现了发布 - 订阅模式的一个典型例子,典型的面向消息的中间件系统包括 JMS(Java Message Service)、ActiveMQ
  • 同异步的实现不同
    • 观察者模式往往以同步的方式实现,即当特定事件发生时,观察者(Observer)的事件处理方法被依次同步调用
    • 发布 - 订阅模式往往以异步的方式实现。当特定事件发生(比如,一个特定的 Topic)时,发布者(Publisher)通知消息队列(Message Queue)或 Broker 对象,此后通知结束。此后,订阅者再去消费这个事件。

Reference