订阅发布模式

场景概述:

  有时需要将多个应用程序集成到一个框架中,这些应用程序常见的基础通信方式包含总线模式、代理模式、

或者点对点模式。一些应用程序发送多种类型的消息,其他应用程序可能更关注这些消息类型的组合。

  例如,在一个金融系统存在多个应用程序管理同一客户信息的情况,存在一个客户关系管理程序(CRM)掌握客户信息。

一种典型的情况:客户信息存在于其他系统中,且这些系统执行各自客户信息管理函数来处理客户信息。

当某个面向客户的应用程序生成更新客户信息的消息,例如客户地址的修改时,CRM和其他管理客户信息的程序

都将到该消息,然而,这个消息类型对于那些不管理客户信息的其他程序是没有意义的。

问题:

  如何才能让一个程序在集成环境中只发送消息到那些对该消息感兴趣的应用程序中,而不需要知道消息接收方

的基本信息?

 约束:

  为确保集成的软件能够只接收到各软件感兴趣的消息,这些软件需要满足下列约束条件:

  1. 集成框架中的应用程序关注不同的消息类型。例如,管理客户信息的应用程序关注客户信息的更新,贸易程序关注买卖事务,用于双向提交事务消息的应用关注消息的提交。

  2. 集成框架中的某个应用可能发送若干个消息类型。例如,应用程序可能发送用户和操作的状态信息。

同样,集成框架中的某个应用通常关注的是其他应用程序发布的消息子集。例如,投资经理只关注那些影响其

所管理的股票的金融信息事务。

  3. 应用程序添加不同信息到消息的情况是多种多样的,这种情况下,固定长度的二进制消息通常是不灵活

的,相比而言,使用封装元素来扩展SOAP(简单对象访问协议)消息更为简单。

  4. 大多数集成框架集成所有的应用,这些应用通常假定在该集成环境中存在同其他应用通信的消息,甚至

对于一个灵活的消息格式,插入或处理应用未知的消息元素都可能遇到困难。

解决方案:

  通过创建主题或动态检测消息内容来扩展通信基础框架。通信框架能确保应用程序能够收到订阅的消息,

并能够创建一种机制来发送消息到所有关注该消息的接收端(订阅方)。

  这里列举了三类创建订阅/发布机制方式:

  1. List-Based Publish/Subscribe(基于列表的订阅发布模式)

  2. Broadcast-Based Publish/Subscribe (基于广播的订阅发布模式)

  3. Content-Based Publish/Subscribe (基于内容的订阅发布模式)

  这三类模式都能够发送消息到所有关注该消息的订阅方。

List-Based Publish/Subscribe (基于列表的订阅发布模式)

  基于列表的订阅发布模式需要管理由订阅方组成的链表,这些订阅方都关注于某一主题。当事件发生时,

订阅方链表上的所有关注该主题的订阅者都将被通知到,这很像常见的观察者模式。当你使用观察者模式时,

需先确定两个类:主题和观察者。假定采用push模式来更新,对于主题(subject)类需要添加三个方法:Attach(), Detach()和Notify(),对于观察者添加Update()方法。

  使用观察者模式时,所有观察者以及其所关注的主题将被注册(使用Attach()方法)。当该主题内容发生

改变时,每个关注该主题的观察者都将被通知到。

  当你创建对象实例并且具体化所有观察者和主题时,使用观察者模式构建订阅发布比较合适, 观察者和主题

的关系要一直保持。通过构建关系数据库,在多对多的情境下,构建主题与观察者的依赖关系。使用时,通过

检索该关系数据库表,即可获取关注某一主题的所有订阅者。

  维护主题和订阅者链表,然后在事件来临时,通知每一个订阅者是基于链表订阅发布实现的基础。

Broadcast-Based Publish/Subscribe(基于广播的订阅发布模式)

  当使用基于广播的订阅发布模式时,事件发布方将创建消息并广播到局域网中,每个监听节点都会检查

消息主题,如果主题为该节点所关注的就会接收并处理该消息。如果该主题不是监听节点关注的,就会忽略该

消息。

  通常主题可以分层并且可能包含多个域,每个域根据周期来分隔,如果需要监听节点可以采用通配符来订阅

某一特殊主题。

  基于广播的订阅发布能够有效的将生产者和消费者解耦,在某些情况,还可以做到区分特殊主题订阅者。

为了区分主题订阅者,协调程序发出消息,订阅该消息的节点将被要求回复,这些响应回复会指明所有该主题

的订阅者。

  这种订阅发布体现在所有的消息都会发布到所有的监听节点,每个节点负责过滤不感兴趣的消息。

Content-Based Publish/Subscribe(基于文本内容的订阅发布模式)

  基于广播和列表的订阅发布基本上都根据主题来分类,都使用预定义主题的方式实现多对多通信。

基于主题和基于内容通信的不同点如下:

  在基于主题的系统,进程交换信息通过一个预订的主题集合,这些主题在多对多的情景下用来区分各

逻辑通道。基于内容的系统更为灵活,因为订阅方与特殊消息内容有关,信息组合的方式被视为动态的

逻辑通道,这极大的扩展了潜在的逻辑通道数量,也改变了订阅发布系统实现的方式。

使用订阅发布

  图一显示四个应用程序集成的一种方案。发送方使用基于主题的方式来发布消息给主题A和主题B。其中

三个接收方订阅这些主题;其中一个订阅了主题A,一个订阅了主题B,一个订阅了主题A和B。箭头描述消息发送

路径。

  实现订阅发布过程,通常影响消息结构,应用集成和通信基础框架。  

  首先, 必须区分主题或应用程序感兴趣的内容。这将转化为将消息类型分为不同的子集。例如在贸易领域

消息类型,一些贸易应用需要追踪买入事务,一些追踪卖出事务,其他应用追踪买卖事务。通过创建买入和卖出

主题来分离消息,并将贸易消息划分到不同子集。

  下一步,必须给消息中添加信息,这些消息指明主题或识别特殊内容信息。有时可以通过保存主题相关的

信息到消息结构的某个未使用的域内。还有一种方式,可以为主题添加一个新的域,例如在SOAP头中添加一个

新的元素。如果既不能使用已存在的域又不能添加,只能找到某种方式将主题嵌入到消息中,或者使用基于

内容的订阅发布方式。

  接下来必须扩展通信基础框架以便消息能够传递给每个订阅者。使用的方法依赖于集成解决方案的拓扑

结构,例如三类普遍的拓扑结构。对于总线结构,可以采用在总线接口上实现订阅机制;对于代理结构,可以

通过为代理者创建订阅者链表来实现;对于点对点结构,可以在发布方创建订阅链表来实现。

  最后,需要修改应用集成框架,发布方必须将与主题相关的信息添加到每个发布的消息中。例如,如果主题

作为头元素编入,发布方必须将主题相关信息插入到合适的位置,同样地,订阅方必须明确感兴趣的主题。

  订阅方可以是固定或动态的,当订阅方是固定的,集成框架设置应用订阅的主题,应用程序无法控制订阅。

通常,订阅过程由每个应用程序在被添加到集成环境时确定。图二显示一个针对主题A的固定订阅方式。

  与之相比,动态订阅能让每个应用程序通过一组控制消息来控制其自身订阅过程。应用程序通过发送消息

到通信基础框架,使其将应用程序从订阅链表中移除,来实现移除订阅内容。大多数提供订阅发布功能的通信

框架都提供该功能,然而,不是非得要动态订阅才能实现这种功能。

  

 上图描述了动态订阅的功能,首先是初始订阅主题A,然后应用发送消息了从订阅链表中移除订阅,接着应用

发送两个消息来订阅主题B和主题C。

相关决定:

  在决定使用订阅发布模式后,需要确定下述要素:

  1. 初始订阅。 必须确定订阅方首次添加到集成环境中如何通过通信框架与订阅内容通信。

  2. 通配符订阅。必须确定是否让订阅发布模式支持通配符订阅。通配符订阅确保订阅者通过一个订阅过程来

订阅多个主题。

  3. 静态或动态订阅。必须确定集成解决方案是动态订阅还是静态订阅。

  4. 主题发现。 必须确定订阅者在解决方案中支持动态订阅的情况下能够发现可以主题。

职责与协作:

  下表为订阅发布个组件的职责和功能。

时间: 2024-11-10 07:24:22

订阅发布模式的相关文章

Publisher/Subscriber 订阅-发布模式

Publisher/Subscriber 订阅-发布模式 本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WCF中的发布订阅,主要参考书籍<Programming WCF Services>,闲话不多说进入正题.使用传统的双工回调(例子 http://www.cnblogs.com/artech/archive/2007/03/02/661969.html)实现发布订阅模式存在许多缺陷,主要问题是,它会引

Spring基于事件驱动模型的订阅发布模式代码实例详解

代码下载地址:http://www.zuidaima.com/share/1791499571923968.htm 原文:Spring基于事件驱动模型的订阅发布模式代码实例详解 事件驱动模型简介 事件驱动模型也就是我们常说的观察者,或者发布-订阅模型:理解它的几个关键点: 首先是一种对象间的一对多的关系:最简单的如交通信号灯,信号灯是目标(一方),行人注视着信号灯(多方): 当目标发送改变(发布),观察者(订阅者)就可以接收到改变: 观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的

JS实现观察者模式(订阅/发布模式)

实现 /*  * js 观察者模式 又称 订阅/发布模式  * 通过创建"可观察"对象,当发生一个感兴趣的事件时可将该事件通告给  * 所有观察者,从而形成松耦合 */ // 通用的发布者 EventPublisher = Base.extend({ publish: function(data, type) { EventPublisher.publish(data, type); } }, { subscribers : {         any : []    // 事件类型:

AngularJS的简单订阅发布模式例子

控制器之间的交互方式广播 broadcast, 发射 emit 事件 类似于 js中的事件 , 可以自己定义事件 向上传递直到 document 在AngularJs中 向上传递直到 rootScope 观察者模式, 订阅发布模式 类似于js中的事件机制 订阅者.on('xx发布博客', function([内容]){ 通知我, 接收到博客的[内容] }) 发布者.emit('xxx发布博客', {内容}) 优点: 业务和实际触发者分离, 代码维护性相对好 缺点: 代码复杂性更高 Angular

RabbitMQ下的生产消费者模式与订阅发布模式

??所谓模式,就是在某种场景下,一类问题及其解决方案的总结归纳.生产消费者模式与订阅发布模式是使用消息中间件时常用的两种模式,用于功能解耦和分布式系统间的消息通信,以下面两种场景为例: 数据接入 ??假设有一个用户行为采集系统,负责从App端采集用户点击行为数据.通常会将数据上报和数据处理分离开,即App端通过REST API上报数据,后端拿到数据后放入队列中就立刻返回,而数据处理则另外使用Worker从队列中取出数据来做,如下图所示. ??这样做的好处有:第一,功能分离,上报的API接口不关心

Node中EventEmitter以及如何实现JavaScript中的订阅/发布模式

1.EventEmitter Node中很多模块都能够使用EventEmitter,有了EventEmitter才能方便的进行事件的监听.下面看一下Node.js中的EventEmitter如何使用. (1)基本使用 EventEmitter是对事件触发和事件监听功能的封装,在node.js中的event模块中,event模块只有一个对象就是EventEmitter,下面是一个最基本的使用方法: var EventEmitter = require('events').EventEmitter;

4 交换机-fanout(订阅发布模式)

目录 订阅发布模式 1.交换器(Exchange) 1.1.创建交换器 1.2 .推送消息到交换器 2.临时队列 3.绑定(bingdings) 5.代码例子 5.1.生产者代码示例 5.2.消费者代码示例 订阅发布模式 1.交换器(Exchange) 在Work Queue背后,其实是rabbitMQ把每条任务消息只发给一个消费者.本篇中我们将要研究如何把一条消息推送给多个消费者,这种模式被称为publish/subscribe(发布/订阅) RabbitMQ的消息发送模型核心思想是生产者不直

Java里观察者模式(订阅发布模式)

创建主题(Subject)接口 创建订阅者(Observer)接口 实现主题 实现观察者 测试 总结 在公司开发项目,如果碰到一些在特定条件下触发某些逻辑操作的功能的实现基本上都是用的定时器 比如用户注册完后,发送邮件,为了防止邮件发送失败或者发送邮件比较耗时,一般也都是通过定时器去扫库里注册没有发邮件的用户数据 再比如一个订单,在改变状态后,要归档,这也是通过定时器来实现的,扫描订单的数据,通过判断状态来做相对应的处理 但这样处理的话,定时器就会越来越多,总觉得不太好 然后,从一些资讯网站上的

【并发】9、借助redis 实现生产消费,消息订阅发布模式队列

这个就是一个消息可以被多次消费的范例了 其实这个实现的方式可以参考我之前的设计模式,观察者模式 https://www.cnblogs.com/cutter-point/p/5249780.html 不过有一点需要注意一下啊,这个消息发布的时候,好像是不支持字节数据的,里面好像会对字节进行转换,这样的结果就是导致我最后无法吧相应的字节转换成我之前序列化的对象 不知道是不是ObjectInputStream和ObjectOutputStream实现不是很好的原因,还是什么,反正反序列化的时候,有些