JBossCache基于jGroups之上,是一个树形结构的,可集群的,事务性的缓存,它可用于非集群的环境中,用来缓存频繁使用的数据在内存中。但JBossCache主要是一个集群的缓存,通常在企业应用集群中使用JBossCache复制节点之间状态,保证企业应用的高可用和容错能力。之前我们对JBossCache做了基本介绍,包括基本API、启动运行、配置部署,监控管理等,这里JBossCache复制示例主要通过图形化或命令行的模式来展示或说明这些知识点。
JBossCache复制示例主要包括两部分,核心部分和展示部分。核心部分包括JBossCache和jGroups,我们知道jGroups是群组通信工具包,JBossCache基于jGroups构建集群缓存。这部分包括JBossCache启动等主要逻辑。展示部分指的是显示界面,我们有三种界面展示JBossCache的树状结构和树中各个节点上的内容,三种界面包括:
根据JBoss Cluster Framework Demo 介绍所示的方法,任意从SourceForge下载或编译生成DEMO_HOME,示例运行启动脚本位于DEMO_HOME/bin目录下,我们知道我们有三种显示界面,接下来我们依次运行显示这三种界面。
./jbosscache.sh -b <node1_IP> -c total-replication.xml
./jbosscache.sh -b <node2_IP> -c total-replication.xml
启动完成后GUI界面显示出来,选择其中任何一界面的跟节点,单击鼠标右键选择“Add to this node”,在弹出添加对话框中添加内容“/a/b/c”,即Fqn路径为“/a/b/c”,我们在跟目录添加了三个节点a,b和c,在添加对话框点击“OK”确认添加后我们去观察另一GUI界面,我们会发现树状结构的节点“/a/b/c”已经复制过去,如下图:
如上面树形结构中,共有四个节点,a,b,c和跟节点,任何一个节点都可以键值对的方式保存数据,在应用中您可通过Fqn路径来获取节点,并对节点数据做更新。在这里我们在任何一界面选择b节点,单击鼠标右键选择“Add/Modify data”,在弹出添加对话框中添加键值对k1/v1,同样我们添加键值对k2/v2和k3/v3。同样我们去观察另一GUI界面,选择b节点,刚才添加的数据也完成了复制,如下图:
同样我们演示局域网内两台机器之间的复制状况。在局域网中的两台机器上分别打开两个终端,进入DEMO_HOME/bin目录,执行:
./jbosscache.sh -b <node1_IP> -c total-replication.xml -console
./jbosscache.sh -b <node2_IP> -c total-replication.xml -console
注意:Windows下使用jbosscache.bat运行JBossCache复制示例。
启动完成后Console界面显示出来,JBossCache复制示例支持的命令如下表:
命令名称 | 描述 |
ls | 显示当前节点下所有节点 |
ls -l | 显示当前节点下所有节点以及节点上对应的内容 |
ls -list | 与ls -l命令功能完全相同 |
tree | 显示整个树节点结构 |
tree -l | 显示整个树节点结构以及节点上对应的内容 |
tree -list | 与tree -l命令功能完全相同 |
cd | 进入到某一节点,后面需要加路径,比如 cda/b/c |
pwd | 显示当前节点位置,类似JBossCacheFqn对应的路径 |
add | 给当前节点添加键值对内容 |
remove | 删除当前节点的内容 |
modify | 修改或更新当前节点的内容 |
add node | 添加节点,比如添要加“a/b/c”,在提示输入Fqn路径时输入“a/b/c” |
remove node | 删除节点,比如要删除“a/b/c”,在提示输入Fqn路径时输入“a/b/c” |
[JBossCache /]add node Enter JBossCache Fully Qualified Name: /a/b/c添加节点成功后我们到另一Console界面运行tree -l命令显示树状结构的节点路径如下:
[JBossCache /]tree -l / - {} └── a - {} └── b - {} └── c - {}我们可以发现新添加的“/a/b/c”已经复制完成,当前JBossCache中共有4个节点,每个节点的都没有任何内容,接下来我们演示向节点b添加内容,并验证添加的内容会同步复制到相对应的JBossCache示例的b节点。我们同样在其中一Console界面运行cd进入到b节点:
[JBossCache /]cd a/b进入b节点后运行add命令,添加键值对k1/v1:
[JBossCache b]add Add/Modify JBossCache via Fully Qualified Name [/a/b] Enter Key: k1 Enter Value: v1使用同样的办法,继续添加键值对k2/v2和k3/v3。同样我们到另一Console界面运行tree -l命令显示树状结构及其各个节点对应的内容:
[JBossCache /]tree -l / - {} └── a - {} └── b - {k3=v3, k1=v1, k2=v2} └── c - {}如上添加在b节点上的内容已经复制到对应树的b节点上。
bsh类似Console,只是console集成在GUI界面,bsh语法类似Java编程语言语法,我们可以通过bsh界面演示JBossCache的事务性。在局域网中的两台机器上分别打开两个终端,进入DEMO_HOME/bin目录,执行:
./jbosscache.sh -b <node1_IP> -c total-replication.xml -bsh
./jbosscache.sh -b <node2_IP> -c total-replication.xml -bsh
同样我们选择两个bsh界面中任何一个,执行添加“a/b/c”路径操作,具体在bsh输入框,依次执行创建Fqn并将创建的Fqn添加到root节点,如下:
root.addChild(Fqn.fromString("/a/b/c"));同样,执行完成后我们可以到另一bsh界面查看树状结构复制状况。接下来我们通过bsh界面演示JBossCache事务性和批量提交。在BeanShell输入框一次运行如下Java语句:
tm = cache.getTransactionManager(); tm.begin(); b = root.getChild(Fqn.fromString("/a/b")); b.put("k1", "v1"); b.put("k2", "v2"); b.put("k3", "v3"); tm.commit();我们可以看到只有当执行提交操作后,键值对k1/v1,k2/v2,k3/v3添加到两个树的b节点。另外下图为我们在bsh界面执行Java语句的截图:
启动JBossCache复制示例时可以添加-debug参数:
./jbosscache.sh -c total-replication.xml -debug这样在DEMO_HOME/log/demo.log中会有详细日志信息,包括节点创建,节点删除,节点内容改变等。在启动示例的console中我们也可以看到相关日志,包括JGroups通道初始化,RPCManagerImpl启动,视图更新等日志,如下:
NFO: JGroups version: 2.6.13.GA --------------------------------------------------------- GMS: address is node1_IP:55250 (cluster=JBossCache-Demo) --------------------------------------------------------- INFO: Received new cluster view: [node1_IP:55250|0] [node1_IP:55250] INFO: JBoss Cache version: JBossCache 'Malagueta' 3.2.5.GA INFO: Received new cluster view: [node1_IP:55250|1] [node1_IP:55250, node2_IP:42039]
如果想查看更详细的日志,我们可以在DEMO_HOME/conf/log4j.xml文件中调整日志级别,这样会有更详细的日志输出。
JBossCache复制示例的源代码位于cluster/jbosscache/demo目录下,接下来我们通过代码端分析来说明以上演示的功能。
160 CacheFactory<String, String> factory = new DefaultCacheFactory<String, String>(); 161 Cache<String, String> cache = factory.createCache(configurationFile, false);如上为JBossCacheView类第160行和161行,这里我们通过JBossCacheDefaultCacheFactory创建缓存,注意createCache()方法的第二个参数为false,表示我们没有默认启动缓存,我们是拿到缓存对象手动启动缓存的。
157 private void handleAddNode() { 158 159 Node parentNode = cache.getNode(Fqn.fromString(getAbsolutePath())); 160 161 String fqn = readString("Enter JBossCache Fully Qualified Name:", true); 162 Node node = parentNode.addChild(Fqn.fromString(fqn)); 163 prompt("Add JBossCache Node, Fully Qualified Name [" + node.getFqn() + "]"); 164 addTreeNode( new TreeNode(fqn, "", getCurrentNode(), null)); 165 }如上为JBossCacheConsole类handleAddNode()方法,当我们执行“add node”命令时此段命令会运行,159行根据Fqn路径获取当前节点,161行从命令行读取Fqn路径,比如“/a/b/c”,162行将读取到的Fqn路径添加到当前节点。
31 @CacheListener 32 public class JBossCacheConsole extends TreeInputConsole { 231 cache.addCacheListener(this); ... 340 }如上为JBossCacheConsole类显示注册添加缓存 Listener的代码,第31行标注JBossCacheConsole类为CacheListener,231行添加加缓存 Listener。
434 @CacheStarted 435 @CacheStopped 436 public void cacheStartStopEvent(Event e){ 440 @NodeCreated 441 @NodeLoaded 442 public void nodeCreated(NodeEvent e) {如上为JBossCacheGUI中注册缓存事件的相关代码。比如434-436行,当缓存启动或停止时,cacheStartStopEvent()方法被调运,相关的启动或停止的事件作为参数传入。
详细关于JBossCache复制示例的代码参照https://github.com/kylinsoong/cluster/tree/master/jbosscache/demo
我们知道JBossCache复制示例在启动时必须通过-c参数指定配置文件(-ctotal-replication.xml),total-replication.xml文件位于DEMO_HOME/conf目录下,查看此文件,我们可以知道相关信息,如我们使用模式为replication,集群的名字为JBossCache-Demo,在示例中我们大多配置项使用默认配置,DEMO_HOME/conf/etc/jbosscache-config-all.xml为一完全JBossCache配置文件。
如前面所描述的,JBosCache可以独立使用即在程序里进行部署,如本示例我们就是在程序中进行部署的,同样JBossCache也可以通过JBoss微容器部署,我们会在以后的例子中演示通过JBoss微容器部署。我们可以通过jconsole对本示例进行监测管理,运行示例后运行jconsole,选择jboss-modules-1.1.2.GA.jar连接,在MBeans列表中选择jboss.cache,我们将看到相关JBossCache统计信息,如下图: