JBoss 系列十七:使用JGroups构建块MessageDispatcher 构建群组通信应用
内容概要
本部分说明JGroups构建块接口MessageDispatcher,具体提供一个简单示例来说明如何使用JGroups构建块MessageDispatcher 构建群组通信应用
示例描述
构建块基于通道之上,是对通道API的更高层抽象,MessageDispatcher提供异步和同步的方法发送消息给集群中的成员并等待响应,我们知道直接使用jGroups API可以向群组发送消息,或从群组接收消息,但发送和接收之间没有任何联系,而使用MessageDispatcher发送消息和接收消息是在同一个事务中完成。本示例演示使用MessageDispatcher 发送消息到集群所有成员并等待响应,验证 GET_ALL 响应模式,超时时间等属性。
示例步骤
本示例集群中有三个成员node1,node2 和node3,node1 为协调者(第一个加入集群)负责集群视图的更新。三个节点都是做相同的事情,向集群中所有节点发送一条消息,并等待接收响应消息。使用JBoss Cluster Framework Demo 介绍所示的方法,任意从SourceForge下载或编译生成DEMO_HOME,本示例的启动脚本msgDispatcher.sh位于DEMO_HOME/bin下。接下来我们依次启动三个节点:
./msgDispatcher.sh -n node1
./msgDispatcher.sh -n node2
./msgDispatcher.sh -n node3
注意,-n指定一个节点名字,Windows操作系统使用对应.bat脚本。
结果分析
1. node1,node2 和node3中任何一个节点启动后我们都可以看到发送消息到群组的日志信息,如下为node1上输出的日志:
16:36:43,699 INFO [MessageDispatcherTest] Casting message to all group members
2. node1,node2 和node3中任何一个节点启动发送完消息后都可以看到群组中返回消息的输出信息,如下为node3上打印输出的响应消息:
Responses:
node3-MessageDispatcher Test Message
node2-MessageDispatcher Test Message
node1-MessageDispatcher Test Message
我们可以看到node3节点打印输出的响应消息有三条,及集群中的所有节点都收到node3发送的消息,且集群中所有节点发送的响应消息都被node3收到。我们可以通过响应模式来控制是否消息发送者要等待所有节点的响应消息,本示例中使用的是 GET_ALL 响应模式,所以只有当接收到所有节点的响应消息或等待超时抛出异常才终止。
3. node1,node2 和node3中任何一个节点启动后的日志中我们可以看到MyRequestHandler处理消息输出的日志,如下为node1上输出的日志:
16:37:11,839 INFO [MyRequestHandler] node3, MessageDispatcher Test Message
4. node1,node2 和node3中任何一个节点运行的日志中我们可以看到MyMembershipListener输出的日志,当群组成员关系发生变化是群视图被打印输出,如下为node1上输出的日志信息:
16:37:11,655 INFO [MyMembershipListener] ViewAccepted, [node1|2] [node1, node2, node3]
[node1|2] [node1, node2, node3]为打印输出的群组视图,node1|2 表示群组的协调者为node1,竖线后面的2表示视图被更新了3次(node1|0,node1|1,node1|2);视图中共有三个成员,即node1,node2 和node3。
代码分析
本示例所有的源代码可以在cluster/jgroups/stu/src/main/java/.../blocks下找到,接下来我们从代码的层面去解释上面的分析结果,这样有助于更直观的理解构建块MessageDispatcher的理解:
47 channel = new JChannel(props);
48 if(null != name) {
49 channel.setName(name);
50 }
51 handler = new MyRequestHandler(channel);
52 messageListener = new MyMessageListener();
53 membershipListener = new MyMembershipListener();
55 disp = new MessageDispatcher(channel, messageListener, membershipListener, handler);
56 channel.connect("MessageDispatcherTestGroup");
58 Util.sleep(100);
59 logger.info("Casting message to all group members");
60 Message message = new Message(null, null, new String("MessageDispatcher Test Message"));
61 rsp_list = disp.castMessage(null, message, new RequestOptions().setMode(ResponseMode.GET_ALL).setTimeout(0));
63 System.out.println("Responses:");
65 List list = rsp_list.getResults();
66 for(Object obj : list) {
67 System.out.println(" " + obj);
68 }
如上47-50行创建一个,设定相应节点的名字;55行实例化一个 MessageDispatcher,我们可以看到,构建块接口是基于通道之上,是对通道的更高层抽象,所以创建 MessageDispatcher时需要传递一个实例化的通道(channel),MessageDispatcher 实例化后通道开始连接到群组(如56行所示);59-61行创建一个消息,通过 castMessage()方法将消息发送到群组,注意,目的地址为空,所以消息接收者为群组所有成员,响应模式为 GET_ALL,所以发送者等待所有成员响应后 castMessage()方法返回,超时时间为 0,即castMessage一直出于等待状态知道所有节点响应消息返回或超时抛出异常;65-68行打印输出所有响应返回消息。
9 public class MyRequestHandler implements RequestHandler {
...
20 public Object handle(Message msg) throws Exception {
21 Address sender = msg.getSrc();
22 logger.info(sender + ", " + msg.getObject());
23 return channel.getName() + "-" + msg.getObject();
24 }
25
26 }
如上第9行,MyRequestHandler实现RequestHandler接口,RequestHandler定义了handle方法,用来处理接收到的消息,20-24行为我们实现的handle方法,我们在日志中记录消息发送者的名字和消息的内容(结果分析第3点node1输出的日志“node3, MessageDispatcher Test Message”表示消息发送着是node3,消息的内容是“MessageDispatcher Test Message”),并将自己的名字和接收到消息的内容返回(结果分析第2点node3输出的日志包括“node1-MessageDispatcher Test Message”表示该响应消息是从node1返回的)。
8 public class MyMembershipListener implements MembershipListener {
...
12 public void viewAccepted(View view) {
13 logger.info("ViewAccepted, " + view);
14 }
如上第8行表示MyMembershipListener实现了MembershipListener接口,MembershipListener接口定义一些成员控制的方法,这里我们实现了viewAccepted()方法,即当群组成员发生变化时该方法被调运,记录群组视图到日志中。
JBoss 系列十七:使用JGroups构建块MessageDispatcher 构建群组通信应用的更多相关文章
- JBoss 系列十九:使用JGroups构建块RspFilter对群组通信返回消息进行过滤
内容概述 本部分说明JGroups构建块接口RspFilter,具体提供一个简单示例来说明如何使用JGroups构建块RspFilter对群组通信返回消息进行过滤. 示例描述 我们知道构建块基于通道之 ...
- JBoss 系列十八:使用JGroups构建块RpcDispatcher构建群组通信应用
内容概要 本部分说明JGroups构建块接口RpcDispatcher,具体提供一个简单示例来说明如何使用JGroups构建块RpcDispatcher构建群组通信应用. 示例描述 类似Message ...
- 企业架构研究总结(35)——TOGAF架构内容框架之构建块(Building Blocks)
之前忙于搬家移居,无暇顾及博客,今天终于得闲继续我的“政治课”了,希望之后至少能够补完TOGAF方面的内容.从前面文章可以看出,笔者并无太多能力和机会对TOGAF进行理论和实际的联系,仅可对标准的文本 ...
- TOGAF架构内容框架之构建块(Building Blocks)
TOGAF架构内容框架之构建块(Building Blocks) 之前忙于搬家移居,无暇顾及博客,今天终于得闲继续我的“政治课”了,希望之后至少能够补完TOGAF方面的内容.从前面文章可以看出,笔者并 ...
- Web 前端开发精华文章集锦(jQuery、HTML5、CSS3)【系列十七】
<Web 前端开发精华文章推荐>2013年第五期(总第十七期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 C ...
- JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景
摘要: 理解Web Workers. 原文:JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这 ...
- 爬虫入门系列(三):用 requests 构建知乎 API
爬虫入门系列目录: 爬虫入门系列(一):快速理解HTTP协议 爬虫入门系列(二):优雅的HTTP库requests 爬虫入门系列(三):用 requests 构建知乎 API 在爬虫系列文章 优雅的H ...
- 线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步
假设多个线程共享一个静态变量,如果让每个线程都执行相同的方法每次让静态变量自增1,这样的做法线程安全吗?能保证自增变量数据同步吗?本篇体验使用lock语句块和Interlocked类型方法保证自增变量 ...
- 现代前端库开发指南系列(二):使用 webpack 构建一个库
前言 在前文中,我说过本系列文章的受众是在现代前端体系下能够熟练编写业务代码的同学,因此本文在介绍 webpack 配置时,仅提及构建一个库所特有的配置,其余配置请参考 webpack 官方文档. 输 ...
随机推荐
- vim的保存文件和退出命令
文章来源:http://blog.sina.com.cn/s/blog_5e357d2d0100zmth.html 命令 简单说明 :w 保存编辑后的文件内容,但不退出vim编辑器.这个命令的作用是把 ...
- Thinkphp模板中函数的使用
1.在模板中使用php函数 在thinkphp的html中,我们经常会遇到一些变量难以直接从php控制端直接处理,这些变量只有在模板中循环输出的时候处理比较合适,这个时候,我们就要在模板中使用函数 1 ...
- python实现RabbitMQ同步跟异步消费模型
1,消息推送类 import pika # 同步消息推送类 class RabbitPublisher(object): # 传入RabbitMQ的ip,用户名,密码,实例化一个管道 def __in ...
- [BZOJ4859][BJOI2017]机动训练(DP)
4859: [BeiJing2017]机动训练 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 105 Solved: 63[Submit][Stat ...
- BZOJ 1109 [POI2007]堆积木Klo(树状数组)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1109 [题目大意] Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体. ...
- 【枚举】【SPFA】Urozero Autumn Training Camp 2016 Day 5: NWERC-2016 Problem I. Iron and Coal
那个人派出的队伍的行走的路径一定前半程是重合的,后半程分叉开来. 于是预处理每个点离1号点的最短路,到最近的铁的最短路,到最近的煤的最短路.(三次BFS / SPFA)然后枚举分岔点,尝试更新答案即可 ...
- 【manacher】HDU4513-吉哥系列故事——完美队形II
[题目大意] 求最长回文队伍且队伍由中间向两边递减. [思路] 和字符串一样的做法,在递推的时候增加判断条件:a[i-p[i]]<=a[i-p[i]+2]. #include<iostre ...
- 【高斯消元解xor方程组】BZOJ2466-[中山市选2009]树
[题目大意] 给出一棵树,初始状态均为0,每反转一个节点的状态,相邻的节点(父亲或儿子)也会反转,问要使状态均为1,至少操作几次? [思路] 一场大暴雨即将来临,白昼恍如黑夜!happy! 和POJ1 ...
- Linux中的黑洞(black hole)-/dev/null
http://blog.csdn.net/loongshawn/article/details/50514018
- EF 通用数据层类
EF 通用数据层父类方法小结 转载:http://www.cnblogs.com/yq-Hua/p/4165344.html MSSql 数据库 数据层 父类 增删改查: using System; ...