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 官方文档. 输 ...
随机推荐
- linux 服务器之间文件传送
linux 服务器之间文件传送免密码输入传递: expect -c " set timeout 10 spawn scp ××××××.tar.bz2 root@172.16.17.34:/ ...
- window10 Powershell使用curl命令报错解决方法
报错信息:curl : 无法分析响应内容,因为 Internet Explorer 引擎不可用,或者 Internet Explorer 的首次启动配置不完整.请指定 UseBasicParsing ...
- Bzoj1486/洛谷P3199 最小圈(0/1分数规划+spfa)/(动态规划+结论)
题面 Bzoj 洛谷 题解(0/1分数规划+spfa) 考虑\(0/1\)分数规划,设当前枚举到的答案为\(ans\) 则我们要使(其中\(\forall b_i=1\)) \[ \frac{\sum ...
- 洛谷——P1724 东风谷早苗
P1724 东风谷早苗 题目描述 在幻想乡,东风谷早苗是以高达控闻名的高中生宅巫女.某一天,早苗终于入手了最新款的钢达姆模型.作为最新的钢达姆,当然有了与以往不同的功能了,那就是它能够自动行走,厉害吧 ...
- shell 指定行插入
#如果知道行号可以用下面的方法 sed -i '88 r b.file' a.file #在a.txt的第88行插入文件b.txt awk '1;NR==88{system("cat ...
- UML对象图、包图
对象图(Object Diagram)显示了一组对象和他们之间的关系.使用对象图阿狸说明数据结构,类图中的类或组件等实例的快照.对象图和类图一样,反应了系统的静态过程,但它是以实际的或原型化为基础来表 ...
- VB 中DTpicker日期控件的运用
1.如何加载 VB默认的控件栏中是没有DTpicker日期控件的,添加过程:工具--部件--控件--"Microsoft Windows Common Controls-2.6.0&quo ...
- 【最短路】【位运算】It's not a Bug, it's a Feature!
[Uva658] It's not a Bug, it's a Feature! 题目略 UVA658 Problem PDF上有 试题分析: 本题可以看到:有<=20个潜在的BUG,那 ...
- 将springboot配置文件中的值注入到静态变量
SpringBoot配置文件分为.properties和.yml两种格式,根据启动环境的不同获取不同环境的的值. spring中不支持直接注入静态变量值,利用spring的set注入方法注入静态变量 ...
- LinkedList源码及解析
package java.util; import java.util.function.Consumer; /** * LinkedList基于链表实现 * 实现了List.Deque.Clonea ...