内容概要

本部分说明JGroups构建块接口RpcDispatcher,具体提供一个简单示例来说明如何使用JGroups构建块RpcDispatcher构建群组通信应用。

示例描述

类似MessageDispatcher,RpcDispatcher同属构建块主要接口,构建块基于通道之上,是对通道API的更高层抽象。程序设计者可以使用RpcDispatcher调运集群中任何节点上的任何方法,并等待所有节点上的返回。本示例使用 RpcDispatcher 提供的 callRemoteMethods() 方法调运集群中所有成员的方法,并验证返回的 RspList 对象中远程方法返回的结果,我们同样也验证 GET_ALL 响应模式,超时时间等属性。

示例步骤

本示例集群中有三个成员node1,node2 和node3,node1 为协调者(第一个加入集群)负责集群视图的更新。RpcMethods类定义了getNodeName()方法,三个节点都是做相同的事情,调运集群中所有节点上RpcMethods类的getNodeName()方法,并等待该方法的返回。使用JBoss Cluster Framework Demo 介绍所示的方法,任意从SourceForge下载或编译生成DEMO_HOME,本示例的启动脚本rpcDispatcher.sh位于DEMO_HOME/bin下。接下来我们依次启动三个节点:

./rpcDispatcher.sh -n node1
./rpcDispatcher.sh -n node2
./rpcDispatcher.sh -n node3

注意,-n指定一个节点名字,Windows操作系统使用对应.bat脚本。

结果分析

1. node1,node2 和node3中任何一个节点启动后我们都可以看到调运群组成员getNodeName()方法的日志信息,如下为node1上输出的日志:

21:41:58,832 INFO  [RpcDispatcherTest] Call all members getNodeName()

2. node1,node2 和node3中任何一个节点启动调运群组成员getNodeName()方法,可以看到远程方法的返回输出信息,如下为node3上打印输出远程方法的返回:

Responses:
node2
node1
node3

我们可以看到node3打印输出的方法返回有三条,这说明群组中所有节点上的getNodeName()被方法,且都正确返回。我们可以控制集群中方法返回的模式,比如我们可以指定模式为GET_FIRST,该模式表示如果集群中有任何一个节点的方法返回,callRemoteMethods()就返回;模式GET_MAJORITY表示如果集群中大多数节点的方法返回,比如集群中有三个节点,如果有两个节点返回,callRemoteMethods()就返回;本示例使用GET_ALL模式,所以等待所有节点的方法返回后callRemoteMethods()才返回。

3. node1,node2 和node3中任何一个节点运行的日志中我们可以看到MyMembershipListener输出的日志,当群组成员关系发生变化是群视图被打印输出,如下为node1上输出的日志信息:

21:42:11,942 INFO  [MyMembershipListener] ViewAccepted, [node1|1] [node1, node2]

[node1|2] [node1, node2, node3]为打印输出的群组视图,node1|2 表示群组的协调者为node1,竖线后面的2表示视图被更新了3次。

4. node1,node2 和node3中任何一个节点启动后的日志中我们可以看到RpcMethods中getNodeName()被调运时输出的日志,如下为node1上输出的日志:

21:42:24,563 INFO  [RpcMethods] node3

如上为RpcMethods类的getNodeName()方法调运时输出日志,我们将在代码分析部分解释为什么node1节点上会打印输出node3的名字。

代码分析

本示例所有的源代码可以在cluster/jgroups/stu/src/main/java/.../blocks下找到,接下来我们从代码的层面去解释上面的分析结果,这样有助于更直观的理解构建块RpcDispatcher的理解。

30                 channel = new JChannel();
31 if(null != name) {
32 channel.setName(name);
33 }
34
35 messageListener = new MyMessageListener();
36 membershipListener = new MyMembershipListener();
37 rpcMethods = new RpcMethods(channel);
38 disp = new RpcDispatcher(channel, messageListener, membershipListener, rpcMethods);
39 channel.connect("RpcDispatcherContentTestGroup");

如上30-33行初始化一个jGroups通道,并设定通道的名称;35-38行分别初始化MyMessageListener,MyMembershipListener,RpcMethods,接着初始化RpcDispatcher,除了MyMessageListener,MyMembershipListener,RpcMethods外,我们还需要将通道实例作为构造方法参数来初始化RpcDispatcher,这也可以说明构建块是基于通道之上的;39行通道连接到集群,通道只有在连接状态才可以相互交互信息。

42                 String param = channel.getName();
43 MethodCall call = new MethodCall("getNodeName", new Object[]{param}, new Class[]{String.class});
44 logger.info("Call all members getNodeName()");
45 RequestOptions requestOptions = new RequestOptions(ResponseMode.GET_ALL, 0);
46 rsp_list = disp.callRemoteMethods(null, call, requestOptions);
47
48 System.out.println("Responses:");
49 List<String> list = rsp_list.getResults();
50 for(Object obj : list) {
51 System.out.println(" " + obj);
52 }

如上42-46行通过RpcDispatcher的 callRemoteMethods()方法调运集群中的方法,MethodCall实例指定远程方法名为getNodeName,传递的参数为当前节点的名字,ResponseMode.GET_ALL表示我们使用GET_ALL模式,即等待所以节点方法返回,callRemoteMethods中参数为null,表明所有节点上的方法被调运;48-52为打印输出方法返回的结果。

8 public class MyMembershipListener implements MembershipListener {
...
12 public void viewAccepted(View view) {
13 logger.info("ViewAccepted, " + view);
14 }

如上第8行表示MyMembershipListener实现了MembershipListener接口,MembershipListener接口定义一些成员控制(新成员加入集群,集群中节点异常)的方法,这里我们实现了viewAccepted()方法,即当群组成员发生变化时该方法被调运,记录群组视图到日志中。

6 public class RpcMethods {
...
24 public String getNodeName(String name) {
25 logger.info(name);
26 return channel.getName();
27 }

如上我们可以看到RpcMethods类getNodeName方法传入参数为调运者节点的名字,我们将调运者的名字日志输出,并将自己的名字返回,所以我们在结果分析第4部分看到node1上输出node3名字,这是由于node3通过 callRemoteMethods()调运了node1节点上的getNodeName方法。

JBoss 系列十八:使用JGroups构建块RpcDispatcher构建群组通信应用的更多相关文章

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

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

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

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

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

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

  4. 学习ASP.NET Core Razor 编程系列十八——并发解决方案

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. 为什么不建议给MySQL设置Null值?《死磕MySQL系列 十八》

    大家好,我是咔咔 不期速成,日拱一卒 之前ElasticSearch系列文章中提到了如何处理空值,若为Null则会直接报错,因为在ElasticSearch中当字段值为null时.空数组.null值数 ...

  6. JBoss 系列十四:JBoss7/WildFly如何加载外部的文件或properties文件

    http://www.tuicool.com/articles/M7ZR3y 原文 http://blog.csdn.net/kylinsoong/article/details/12623997 主 ...

  7. BizTalk开发系列(十八) 使用信封拆分数据库消息

    之前写了一篇的<BizTalk开发系列(十七) 信封架构(Envelop)> 是关于信封架构及其拆装原理的,都是理论性的内容.信封在BizTalk开发过程中最常用的应该是在读取SQL Se ...

  8. angular学习笔记(二十八)-$http(6)-使用ngResource模块构建RESTful架构

    ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...

  9. WPF入门教程系列十八——WPF中的数据绑定(四)

    六.排序 如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider.CollectionViewSource 则会 ...

随机推荐

  1. 洛谷P3385 [模板]负环 [SPFA]

    题目传送门 题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个 ...

  2. Sqli-labs less 6

    Less-6 Less6与less5的区别在于less6在id参数传到服务器时,对id参数进行了处理.这里可以从源代码中可以看到. $id = '"'.$id.'"'; $sql= ...

  3. oracle substr

    SUBSTR( string, start_position [, length ] ) Parameters or Arguments string The source string. start ...

  4. [CODE FESTIVAL 2016]Encyclopedia of Permutations

    题意:给定一个排列,其中有可能有一些未确定的数,求出所有可能的排列的排名之和 首先我们要知道怎么算一个给定排列的排名,设它为$p_{1\cdots n}$ 排名即为比它小的排列数$+1$,对于每一个比 ...

  5. bzoj 2073: [POI2004]PRZ

    2073: [POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的 ...

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

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

  7. 基于socket的udp传输,socketserver模块,进程

    基于UDP的套接字 udp是无连接的,先启动哪一端都不会报错 socket.SOCK_DGRAM 数据报协议 udp不会发送空数据,什么都不输入直接发送也会有报头发过去 服务端 import sock ...

  8. cocos2d-x解析xml时的Bug

    cocos2d-x中使用tinyxml解析xml配置.如下: tinyxml2::XMLDocument doc; if (tinyxml2::XML_SUCCESS != doc.LoadFile( ...

  9. mvn在线仓库搜索

    使用Maven进行开发的时候,比较常见的一个问题就是如何寻找我要的依赖,比如说,我想要使用activeMQ,可是我不知道groupId,artifactId,和合适的version.怎么办呢?本文介绍 ...

  10. ORADEBUG DOC 12.1.0.2

     https://berxblog.blogspot.com/2015/01/oradebug-doc-12102.html   this is just an online docu of ORAD ...