内容概要

本部分说明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 构建群组通信应用的更多相关文章

  1. JBoss 系列十九:使用JGroups构建块RspFilter对群组通信返回消息进行过滤

    内容概述 本部分说明JGroups构建块接口RspFilter,具体提供一个简单示例来说明如何使用JGroups构建块RspFilter对群组通信返回消息进行过滤. 示例描述 我们知道构建块基于通道之 ...

  2. JBoss 系列十八:使用JGroups构建块RpcDispatcher构建群组通信应用

    内容概要 本部分说明JGroups构建块接口RpcDispatcher,具体提供一个简单示例来说明如何使用JGroups构建块RpcDispatcher构建群组通信应用. 示例描述 类似Message ...

  3. 企业架构研究总结(35)——TOGAF架构内容框架之构建块(Building Blocks)

    之前忙于搬家移居,无暇顾及博客,今天终于得闲继续我的“政治课”了,希望之后至少能够补完TOGAF方面的内容.从前面文章可以看出,笔者并无太多能力和机会对TOGAF进行理论和实际的联系,仅可对标准的文本 ...

  4. TOGAF架构内容框架之构建块(Building Blocks)

    TOGAF架构内容框架之构建块(Building Blocks) 之前忙于搬家移居,无暇顾及博客,今天终于得闲继续我的“政治课”了,希望之后至少能够补完TOGAF方面的内容.从前面文章可以看出,笔者并 ...

  5. Web 前端开发精华文章集锦(jQuery、HTML5、CSS3)【系列十七】

    <Web 前端开发精华文章推荐>2013年第五期(总第十七期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 C ...

  6. JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景

    摘要: 理解Web Workers. 原文:JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这 ...

  7. 爬虫入门系列(三):用 requests 构建知乎 API

    爬虫入门系列目录: 爬虫入门系列(一):快速理解HTTP协议 爬虫入门系列(二):优雅的HTTP库requests 爬虫入门系列(三):用 requests 构建知乎 API 在爬虫系列文章 优雅的H ...

  8. 线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步

    假设多个线程共享一个静态变量,如果让每个线程都执行相同的方法每次让静态变量自增1,这样的做法线程安全吗?能保证自增变量数据同步吗?本篇体验使用lock语句块和Interlocked类型方法保证自增变量 ...

  9. 现代前端库开发指南系列(二):使用 webpack 构建一个库

    前言 在前文中,我说过本系列文章的受众是在现代前端体系下能够熟练编写业务代码的同学,因此本文在介绍 webpack 配置时,仅提及构建一个库所特有的配置,其余配置请参考 webpack 官方文档. 输 ...

随机推荐

  1. 590. N叉树的后序遍历

    给定一个 N 叉树,返回其节点值的后序遍历. 例如,给定一个 3叉树 : 返回其后序遍历: [5,6,3,2,4,1]. 说明: 递归法很简单,你可以使用迭代法完成此题吗? /* // Definit ...

  2. 洛谷——P1626 象棋比赛

    P1626 象棋比赛 题目描述 有N个人要参加国际象棋比赛,该比赛要进行K场对弈.每个人最多参加两场对弈,最少参加零场对弈.每个人都有一个与其他人不相同的等级(用一个正整数来表示). 在对弈中,等级高 ...

  3. HDU 5862 Counting Intersections(离散化 + 树状数组)

    Counting Intersections Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  4. JDBC 编程初步

    JDBC 概述 什么是JDBC 是一种用于执行SQL语句的Java API,它由一组用Java语言编写的类和接口组成,JDBC提供了一种操作数据的标准,JDBC的目标是使Java程序员使用JDBC可以 ...

  5. BZOJ 2157 旅游(动态树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2157 [题目大意] 支持修改边,链上查询最大值最小值总和,以及链上求相反数 [题解] ...

  6. 20162312实验四Java Android简易开发

    实验准备 Android Studio 的下载: Android Studio 安装教程 准备中遇到的问题 最大的问题就是电脑无法虚拟化,因为微星的型号太多,我只好在网上找了许多方案一个个试,最后终于 ...

  7. Table 'hd_online' is marked as crashed and should be repaired索引损坏

    myisam 引擎表的索引损坏,解决方法 找到mysql的安装目录的/usr/local/mysql/bin/myisamchk工具,在命令行中输入: myisamchk -c -r /data/db ...

  8. centos6.5编译安装nginx

    系统64位 centos6.5 nginx官网:http://nginx.org/ 下载nginx源码包: wget  http://nginx.org/download/nginx-1.6.2.ta ...

  9. a标签点击后页面显示个false

    最近遇到个问题,在html页面中使用a标签,在href属性中调用一个function,而function中返回的是return false.结果页面被跳转了,然后页面上显示一个false. 一看到这个 ...

  10. [Bug]Object reference not set to an instance of an object.

    引言 今天在客户这儿,由一个问题导致,需求的变化,不得不修改代码,在记录日志中出现该问题. 原因 通过id查找相关信息,没有判断是否为null,集合是否有数据. Object reference no ...