一、     什么是Broker云

  Apathe Qpid 支持Broker Federation ,也就是Broker联盟或者叫做Broker云。Broker Federation可以通过配置消息路由,创建一个可以让特定的消息可以从源broker自动路由到目标broker的消息系统网络。Broker Federation通常在一个包含大量broker的大网络环境中使用。如果网络互联允许,完全可以在单独的一个网络位置配置整个Broker云消息系统网络。当Broker服务主机发生变化时,Broker云内部的路由规则可以根据时间、拓扑等等条件动态地变化和适应。

  Broker Federation可以适用于各种各样的场景,只要能够依据一定的规则来组织不同的broker逻辑区域。Broker Federation的应用场景举例:

地理位置:路由客户的请求到最近的工作服务站点。

服务类型:高端客户的请求需要路由到响应更迅速的服务站点。

负载均衡:Brokers之间的路由可以动态适应当前或预期的负载情况。

WAN连通性:不同地域的Brokers之间路由通过广域网连接,客户端只需要连接到本地Broker,分散各地域的brokers同样可以提供消息分发和存储。

功能性组织:根据不同软件系统之间的消息流可反映出一个分布式系统的逻辑结构。

可堆叠Exchange高性能交换器比如xml exchange,可以通过堆叠来提高性能。

跨科跨部门工作流:根据不同Brokers之间的消息流可反映出跨科跨部门组织之间的工作流。

下图是一个根据地理位置划分区域后部署的Broker云,各个城市之间的主机完全可以自由交换消息。

二、     消息路由

  一个Broker Federation需要通过创建消息路由才能实现。每条消息路由是单向的,如果需要双向,可以通过在两个方向各创建一条路由来实现。路由的目的地址总是目标Broker的exchange,源地址可以是源Broker的exchange,或queue。一般情况下,在目标Broker内部创建路由,向源Broker订阅相应的地址,这种路由是拉式路由。相反,在源Broke创建路由,向目标Broker推送消息到指定的地址,这是推式路由。多个源Broker指定同一个目标Broker时,推方式路由效率更高。路由也支持持久化。

  有三种路由,Queue路由,Exchange路由和动态Exchange路由,其中前面两种属于静态路由。

Queue路由:Broker A的某个queue地址中的所有消息路由到Broker B的某个exchange。

Exchange路由:Broker A 某个Exchange中匹配指定Binding Key(Routing key,可理解为消息主题)的所有消息路由到Broker B 的同名Exchange中去。当然,对于fanout型的Exchange,binding key是忽略的。

动态Exchange路由:客户端订阅Broker A指定Binding key的某个Exchange地址,若Broker A通过动态Exchange路由连接到Broker B,则客户端不仅可以接收到Broker A的该Exchange地址上匹配Binding Key的消息,同时也可以接收Broker B 的相同名字的Exchange地址上匹配Binding Key的消息。这里的Binding是可以动态变更的。动态路由接收两个Broker之间同名Exchange之间的所有Binding key。动态路由其实是一种特殊的Exchange路由,区别是所有Binding Key都可以动态自动指定,无需手动显式指定,但它只能是拉式路由。

三、     拓扑结构

使用双向路由,可以实现星形、树形或线形的拓扑。如果在环形的拓扑使用,只能使用单向路由。

星形拓扑:

 

 

树形拓扑:

 

线形拓扑:

 

环形拓扑:

消息传递过程总是需要一定的时间的,因此在设计拓扑结构时,一条消息的完整路径所经过的broker节点尽可能要少。大多数情况下,树形或星形拓扑可以满足大多数需求,同时能够很好的防止消息环路的发生。

在一个拓扑中的任何两个Broker节点A、B,应该有且只有一条路由路径。如果有多于一条路径,会导致消息环路,出现消息重复甚至消息风暴。

四、     Broker Federation跟高可用集群结合

  Broker云同样可以应用在部署了HA集群的网络环境,这时,每一个HA集群看作是单个Broker节点。建立消息路由时,可以连接一个HA集群里的任意一个Broker到另一个HA集群里的任意一个Broker。在同一个集群内部,每个Broker都可以共享同一个集群内部所建立的其他消息路由。

五、     qpid-route命令行工具的使用

操作系统:CentOS 6.5 i386

Apache Qpid版本:qpid-cpp 0.32

qpid-route需要安装qpid-qmf-0.32.tar.gz。

主机名

IP地址

node1.example.com

192.168.15.16

node2.example.com

192.168.15.69

Queue路由

首先,在node2创建一个名为public 的queue;

[root@node1 ~]# qpid-config -b node2.example.com add queue public

[root@node1 ~]# qpid-route queue add node1.example.com node2.example.com amq.fanout public

查看路由拓扑

[root@node1 ~]# qpid-route route map node1.example.com

Finding Linked Brokers:

node1.example.com:5672... Ok

node2.example.com:5672... Ok

Dynamic Routes:

none found

Static Routes:

node1.example.com:5672(ex=amq.fanout) <= node2.example.com:5672(queue=public)

[root@node1 ~]#

查看连接状态

[root@node1 ~]# qpid-route link list node1.example.com

Host          Port    Transport Durable  State             Last Error

===================================================================

node2.example.com5672    tcp    N     Operational

[root@node1 ~]#

订阅node1的amq.fanout地址

[root@node1 messaging]# ./drain -b node1.example.com -t 60  amq.fanout

然后向node2的public地址发送消息

[root@node1 messaging]# ./spout -b node2.example.com --content 123456 public

Message(properties={spout-id:13812f41-d342-4fb9-9254-863fcd1e8fe5:0}, content='123456')

意料之内,node2上的public的消息路由到node2的amq.fanout地址

[root@node1 messaging]# ./drain -b node1.example.com -t 60  amq.fanout

Message(properties={spout-id:13812f41-d342-4fb9-9254-863fcd1e8fe5:0, x-amqp-0-10.routing-key:public}, content='123456')

清除queue 路由

[root@node1 messaging]# qpid-route queue del node1.example.com node2.example.com amq.fanout public

Exchange路由

[root@node1 messaging]# qpid-route route add node1.example.com node2.example.com amq.topic global.#

[root@node1 messaging]# qpid-route route map node1.example.com

Finding Linked Brokers:

node1.example.com:5672... Ok

node2.example.com:5672... Ok

Dynamic Routes:

none found

Static Routes:

node1.example.com:5672(ex=amq.topic) <= node2.example.com:5672(ex=amq.topic) key=global.#

[root@node1 messaging]#

向node2的amq.topic地址发送主题带global的消息,观察该消息是否正确路由到node1的amq.topic地址

首先订阅node1地址amq.topic

[root@node1 messaging]# ./drain -b node1.example.com -t 60  amq.topic

然后,向node2的地址amq.topic发送带global主题的消息

[root@node1 messaging]# ./spout -b node2.example.com --content 123456 amq.topic/global.aaa.bbb

Message(properties={spout-id:2fb5de3d-b3a0-449b-8810-c8b9cb617011:0}, content='123456')

可以观察到,消息正确被路由了

[root@node1 messaging]# ./drain -b node1.example.com -t 60  amq.topic

Message(properties={qpid.subject:global.aaa.bbb, spout-id:2fb5de3d-b3a0-449b-8810-c8b9cb617011:0, x-amqp-0-10.routing-key:global.aaa.bbb, x-qpid.trace:cad71590-80e1-4dcc-81eb-2ee49df2a1b3}, subject='global.aaa.bbb', content='123456')

清除路由

[root@node1 messaging]# qpid-route route del node1.example.com node2.example.com amq.topic global.#

动态Exchange路由

首先,分别在node1,node2创建一个topic 的exchange  fed.topic

[root@node1 messaging]# qpid-config -b node1.example.com add exchange topic fed.topic

[root@node1 messaging]# qpid-config -b node2.example.com add exchange topic fed.topic

创建两条动态消息路由,实现双向传递

[root@node1 messaging]# qpid-route dynamic add node1.example.com node2.example.com fed.topic

[root@node1 messaging]# qpid-route dynamic add node2.example.com node1.example.com fed.topic

查看路由

[root@node1 messaging]# qpid-route route map node1.example.com

Finding Linked Brokers:

node1.example.com:5672... Ok

node2.example.com:5672... Ok

Dynamic Routes:

Exchange fed.topic:

node2.example.com:5672 <=> node1.example.com:5672

Static Routes:

none found

[root@node1 messaging]#

在node1订阅地址fed.topic

[root@node1 messaging]# ./drain -b node1.example.com -t 60  fed.topic

向node2地址fed.topic发送任意主题消息

[root@node1 messaging]# ./spout -b node2.example.com --content 123456 fed.topic/global

Message(properties={spout-id:bec400b9-21ba-4b44-9a64-8c78a0003e7f:0}, content='123456')

[root@node1 messaging]# ./spout -b node2.example.com --content 123456 fed.topic/xxxxx

Message(properties={spout-id:bfa28743-4208-4d4d-96a3-e21c9af482a7:0}, content='123456')

可以观察到,node1上接收了所有node2上fed.topic所有消息

[root@node1 messaging]# ./drain -b node1.example.com -t 60  fed.topic

Message(properties={qpid.subject:global, spout-id:bec400b9-21ba-4b44-9a64-8c78a0003e7f:0, x-amqp-0-10.routing-key:global, x-qpid.trace:cad71590-80e1-4dcc-81eb-2ee49df2a1b3}, subject='global', content='123456')

Message(properties={qpid.subject:xxxxx, spout-id:bfa28743-4208-4d4d-96a3-e21c9af482a7:0, x-amqp-0-10.routing-key:xxxxx, x-qpid.trace:cad71590-80e1-4dcc-81eb-2ee49df2a1b3}, subject='xxxxx', content='123456')

同样,反过来测试,结果也一样。

[root@node1 messaging]# ./spout -b node1.example.com --content 123456 fed.topic/global

Message(properties={spout-id:00aaf56e-6282-436a-81ed-638baaa48737:0}, content='123456')

[root@node1 messaging]# ./spout -b node1.example.com --content 123456 fed.topic/xxxxx

Message(properties={spout-id:ceca4150-e2a0-4d3b-b04a-d81deffc9709:0}, content='123456')

[root@node1 messaging]# ./drain -b node2.example.com -t 60  fed.topic

Message(properties={qpid.subject:global, spout-id:00aaf56e-6282-436a-81ed-638baaa48737:0, x-amqp-0-10.routing-key:global, x-qpid.trace:aae222c1-d458-4aeb-a8f0-045211bf1e8d}, subject='global', content='123456')

Message(properties={qpid.subject:xxxxx, spout-id:ceca4150-e2a0-4d3b-b04a-d81deffc9709:0, x-amqp-0-10.routing-key:xxxxx, x-qpid.trace:aae222c1-d458-4aeb-a8f0-045211bf1e8d}, subject='xxxxx', content='123456')

可以这样理解,node1和node2的fed.topic是可以看作是一体的,任意一个节点的fed.topic收到的消息,都会路由到另一个节点的fed.topic那里,并且binding key保持一致。

清除路由

[root@node1 messaging]# qpid-route dynamic del node2.example.com node1.example.com fed.topic

[root@node1 messaging]# qpid-route dynamic del node1.example.com node2.example.com fed.topi

PS:在需要应用流控的场景,exchange路由并不能很好的触发流控,而且会出现路由自动断开并自动重建的抖动现象,而queue路由则能很好工作,估计这是一个bug。

Apache Qpid Broker云的更多相关文章

  1. Apache Qpid Broker的安全机制

    一.     Apache Qpid的安全机制简介 Apache Qpid提供多种安全机制,包括用户认证.规则定制的授权.消息加密和数字签名等.Apache Qpid使用SASL框架实现对用户身份的认 ...

  2. Apache Qpid Python 1.35.0 发布

    Apache Qpid Python 1.35.0 发布了,Apache Qpid (Open Source AMQP Messaging) 是一个跨平台的企业通讯解决方案,实现了高级消息队列协议.提 ...

  3. Apache Qpid 高可用集群

    一.RHCS RHCS是Red Hat Cluster Suite(红帽子集群套件)的缩写.RHCS是一个功能完备的集群应用解决方案,它从应用的前端访问到后端的数据存储都提供了一个行之有效的集群架构实 ...

  4. Apache Qpid CPP的编译与安装

    单机Broker部署(windows/linux) 在Windows/Linux上部署QPID Broker的方法. Windows 需要预先准备的文件和程序 qpid-cpp-0.32.tar.gz ...

  5. 基于Apache的阿里云部署Node.js服务器(Windows环境)

    1 前言 由于nodejs项目对方开放了多个端口,而且阿里云上的Apache服务器(windows)已经挂载了网站,此时需要把此项目也挂上去,网上查询资料,方法略少,基本是基于nginx版本的. 2  ...

  6. centos apache 腾讯云ssl证书配置

    首先向证书机构申请https证书,会得到证书和私钥,这里我以腾讯云证书安装为例(非常简单) 分两步走 1.申请 点击腾讯云控制台->产品模块下的ssl证书管理->点击申请证书(免费的,不要 ...

  7. Apache Hudi:云数据湖解决方案

    1. 引入 开源Apache Hudi项目为Uber等大型组织提供流处理能力,每天可处理数据湖上的数十亿条记录. 随着世界各地的组织采用该技术,Apache开源数据湖项目已经日渐成熟. Apache ...

  8. Apache Qpid消息通讯模型和消息地址简介

    Broker知识准备 Broker内置两种节点类型:一种是 queue,一种是 topic. 1.  queue 节点能够缓存消息,直到被读取走为止.queue节点满足两个重要的 PTP 通信的特征, ...

  9. Apache ShardingSphere 5.1.2 发布|全新驱动 API + 云原生部署,打造高性能数据网关

    在 Apache ShardingSphere 5.1.1 发布后,ShardingSphere 合并了来自全球的团队或个人的累计 1028 个 PR,为大家带来 5.1.2 新版本.该版本在功能.性 ...

随机推荐

  1. hdu2051

    二进制转换 #include <stdio.h> void change(int n){ ]; ; while(n){ num[cnt]=n%; n/=; cnt++; } cnt--; ...

  2. 【java基础 10】hash算法冲突解决方法

    导读:今天看了java里面关于hashmap的相关源码(看了java6和java7),尤其是resize.transfer.put.get这几个方法,突然明白了,为什么我之前考数据结构死活考不过,就差 ...

  3. BZOJ 4568 [Scoi2016]幸运数字 ——线性基 倍增

    [题目分析] 考虑异或的最大值,维护线性基就可以了. 但是有多次的询问,树剖或者倍增都可以. 想了想树剖动辄数百行的代码. 算了,我还是写倍增吧. 注:被位运算和大于号的优先级坑了一次,QaQ [代码 ...

  4. [TyvjP1519] 博彩游戏(AC自动机 + DP)

    传送门 和bzoj1030一个德性 #include <queue> #include <cstdio> #include <cstring> #define N ...

  5. Python 可变对象与不可变对象

    1. 不可变(immutable):int.字符串(string).float.(数值型number).元组(tuple) 可变(mutable):字典型(dictionary).列表型(list) ...

  6. [delphi]修改indy源码后重新编译

    http://blog.csdn.net/nerdy/article/details/8702568 虽然indy有一身的毛病,但是一般情况下使用起来还是多方便的. 今天在做一个使用到indy的程序的 ...

  7. hdu - 1269 迷宫城堡 (强连通裸题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1269 判断一个图是不是强连通,缩点之后判断顶点数是不是为1即可. #include <iostream&g ...

  8. BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)

    题目链接 BZOJ 3675 首先最后的答案和分割的顺序是无关的, 那么就可以考虑DP了. 设$f[i][j]$为做了$i$次分割,考虑前$j$个数之后的最优答案. 那么$f[i][j] = max( ...

  9. LCA rmq st model

    LCA:倍增 memset(p,-,sizeof(p)); inline void dfs(int u) { ;i=e[i].next) { int v=e[i].v; ) { deep[v]=dee ...

  10. Spark学习(一) Spark初识

    一.官网介绍 1.什么是Spark 官网地址:http://spark.apache.org/ Apache Spark™是用于大规模数据处理的统一分析引擎. 从右侧最后一条新闻看,Spark也用于A ...