目录编程
熟悉消息中间件的同窗应该对发布/订阅模式(Publish Subscribe Pattern)并不陌生。即便你不了解消息中间件,那么在平时生活中发布/订阅模式也是很是常见的场景。设计模式
好比你打开你的微信订阅号,你订阅的做者发布的文章,会广播给每一个订阅者。在这个场景里,微信公众号就是一个Pulisher,而你就是一个Subscriber,你收到的文章就是一个Message。安全
下面咱们就一块儿了解一下发布/订阅模式
,若是你要了解并在本身的项目中使用这个模式,或者你对消息队列(MQ)等中间件的原理感兴趣,那么这个系列的文章就是最高效地深刻浅出宝典。服务器
发布/订阅模式(Publish Subscribe Pattern)属于设计模式中的行为(Behavioral Patterns)。微信
在软件架构中,发布/订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者),而是经过消息通道广播出去,让订阅改消息主题的订阅者消费到。架构
发布/订阅者模式
最大的特色就是实现了松耦合,也就是说你可让发布者发布消息、订阅者接受消息,而不是寻找一种方式把两个分离的系统链接在一块儿。固然这种松耦合也是发布/订阅者模式
最大的缺点,由于须要中间的代理,增长了系统的复杂度。并且发布者没法实时知道发布的消息是否被每一个订阅者接收到了,增长了系统的不肯定性。异步
发布/订阅者模式
的优势发布/订阅者模式
的优势能够概括为:编程语言
发布/订阅者模式
能够将众多须要通讯的子系统(Subsystem)解耦,每一个子系统均可以独立管理。并且即便部分子系统下线了,也不会影响系统消息的总体管理。测试
发布/订阅者模式
为应用程序提供了关注点分离。每一个应用程序均可以专一于其核心功能,而消息传递基础结构负责将消息路由到每一个消费者手里。设计
发布/订阅者模式
增长了系统的可伸缩性,并提升了发送者的响应能力。缘由是发送方(Publisher)能够快速地向输入通道发送一条消息,而后返回到其核心处理职责,而没必要等待子系统处理完成。而后消息传递的基础结构负责确保把消息传递到每一个订阅者(Subscriber)手里。
发布/订阅者模式
提升了可靠性。异步的消息传递有助于应用程序在增长的负载下继续平稳运行,而且能够更有效地处理间歇性故障。
你不须要关心不一样的组件是如何组合在一块儿的,只要他们共同遵照一份协议便可。
发布/订阅者模式
容许延迟处理或者按计划的处理。例如当系统负载大的时候,订阅者能够等到非高峰时间才接收消息,或者根据特定的计划处理消息。
发布/订阅者模式
提升了可测试性。通道能够被监视,消息能够做为总体集成测试策略的一部分而被检查或记录。
发布/订阅者模式
须要考虑的点订阅者能够在消息通道中订阅或者取消订阅某个话题。
链接到任何消息通道必须受到安全策略的限制,以防止未经受权的用户或应用程序窃听。
根据每条消息的内容检查和分发消息。每一个订户均可以指定其感兴趣的内容。
订阅者一般只对发布者分发的消息的子集感兴趣。消息服务一般容许订户缩小如下用户接收到的消息集。
考虑容许订户经过通配符订阅多个主题。每一个主题都有一个专用的输出通道,每一个使用者均可以订阅全部相关主题。
发布订阅系统中的通道被视为单向的。
若是特定订户须要向发布服务器发送确认或通讯状态,请考虑使用请求/回复模式。此模式使用一个通道向订阅服务器发送消息,以及一个单独的回复通道向发布服务器进行通讯。
使用者实例接收消息的顺序不必定获得保证,也不必定反映消息的建立顺序。
设计该系统以确保消息处理是等量的,以帮助消除对消息处理顺序的任何依赖。
有些解决方案可能须要按特定顺序处理消息。优先级队列模式提供了一种确保特定消息先于其余消息传递的机制。
格式错误的消息或须要访问不可用资源的任务可能会致使服务实例失败。系统应防止此类消息返回到队列,不然可能致使系统故障。
同一消息可能会发送屡次。例如,发送者可能在发布消息后出现了异常,没有记录本身已经成功发送了消息,而后,发送者的新实例可能会启动并重复该消息。
消息基础结构应基于消息ID实现重复消息检测和删除(也称为重复数据消除),以便最多提供一次消息传递。
消息的生命周期可能有限。若是在这段时间内没有处理,它可能再也不有价值,应该丢弃。发送方能够指定过时时间做为消息中数据的一部分。在决定是否执行与消息关联的业务逻辑以前,接收者能够检查此信息,以确保消息没有过时。
例如,消息可能会被暂时禁止,直到特定的日期和时间才被处理。
发布/订阅者模式
若是你的程序只有不多的订阅者,或者须要与子系统进行实时的交互,那么发布/订阅者模式
是不适合的。
在如下状况下能够考虑使用此模式:
应用程序须要向大量消费者广播信息。例如微信订阅号就是一个消费者量庞大的广播平台。
应用程序须要与一个或多个独立开发的应用程序或服务通讯,这些应用程序或服务可能使用不一样的平台、编程语言和通讯协议。
应用程序能够向消费者发送信息,而不须要消费者的实时响应。
被集成的系统被设计为支持其数据的最终一致性模型。
应用程序须要将信息传递给多个消费者,这些消费者可能具备与发送者不一样的可用性要求或正常运行时间计划。例如你消息在上午发布了出去,消费者计划在下午才去处理这些消息。
发布/订阅者模式
与观察者模式
发布/订阅者模式
与观察者模式
是咱们常常混淆的两种设计模式,能够说两种设计模式在行为上有必定的类似性,但倒是两种不一样的设计模式。或者说发布/订阅者模式
是观察者模式
的一种变体。
经过下图能够清晰地看到两种设计模式的不一样点。
发布/订阅者模式
与观察者模式
主要有如下几个不一样点:
在观察者模式中,主体维护观察者列表,所以主体知道当状态发生变化时如何通知观察者。然而,在发布者/订阅者中,发布者和订阅者不须要相互了解。它们只需在中间层消息代理(或消息队列)的帮助下进行通讯。
在发布者/订阅者模式中,组件与观察者模式彻底分离。在观察者模式中,主题和观察者松散耦合。
观察者模式主要是以同步方式实现的,即当发生某些事件时,主题调用其全部观察者的适当方法。发布服务器/订阅服务器模式主要以异步方式实现(使用消息队列)。
发布者/订阅者模式更像是一种跨应用程序模式。发布服务器和订阅服务器能够驻留在两个不一样的应用程序中。它们中的每个都经过消息代理或消息队列进行通讯。
本文介绍了发布者/订阅者模式
的相关概念,后面几篇会详细介绍具体实现。