读书人

JGroups系列之引见和体会

发布时间: 2012-11-17 11:14:15 作者: rapoo

JGroups系列之介绍和体会

JGroups系列之介绍和体会

很早就想做这个JGroups系列,因为在分布式的系统中,各个部分经常需要相互通信。这些通信包括:信息需要同时发给集群中的某些或全部的worker;或者一个worker启动、停止需要通知其他的worker;等等。

对于这些问题的解决,我们通常有各种各样的方法。比如,信息需要同时发给集群中的某些或全部的worker,这个问题,我们可能会采用MQ来解决;而对于后者,我们可能会通过维护心跳的方式来解决。

可能我们自己也知道,上述的方法要么太重,如MQ,我们需要维护一个MQ服务器;要么解决起来比较麻烦,如心跳方式。

曾经有一段时间,我在为上面的问题烦心,一直想寻找一个好的解决方案。

直到我发现了JGroups,才发现JGroups已经为我们提供了很好的解决方法。

下面进入JGroups的简要介绍阶段。

JGroups是一个可靠的组播通信工具。

所谓可靠,指的是,你不用为你发出去的消息是否会丢掉而担心,工具为你解决了这个问题。

所谓“组播”,其实JGroups实现了“单播(对点)”、“组播(对组)”和“广播(对所有)”的三种通信方式。

通过上面的介绍,我们就可以知道,JGroups可以帮我们解决“信息需要同时发给集群中的某些或全部的worker”的问题。

同时,当一个JGroups客户端连接到群里,或者跟群断开,群里所有的客户端都会得到通知。这也就解决了第二个问题。

当然,作为组播工具,JGroups的功能远远比我介绍的要强大得多。

这个系列将要介绍的主要包括以下的三个方面的应用:

一、组播功能

这是我们使用JGroups的最基本功能。前面我们说过,MQ也能实现这个功能。但MQ的问题是太重,我们需要维护一个MQ服务器,而MQ更为强大的功能,我们在这里又用不到。

JGroups就为我们提供了一个更好的解决方案,不那么重,我们不需要维护额外的服务器;消息也是可靠的、不会丢失(比我们自己写一个UDP或TCP容易得多)。

二、发现功能

作为一个集群,我们经常需要知道集群里各个worker的运行,即某个worker是否在运行。

JGroups为我们提供了这样一个通知或发现的功能,我们可以很轻松的知道集群里的某个worker是否在运行。

这比心跳程序要简单得多。

三、状态传递

状态传递也是集群中经常要用到的。举个例来说,一个web服务器集群系统,session是需要传递的。即,当一个web服务器宕掉以后,它上面的session需要转移到别的web服务器上去,以便别的web服务器能够继续给拥有该session的用户提供服务。

JGroups拥有状态传递的功能,这是分布式系统相当有用的一个功能。

除此之外,还会有一些在JGroups工作过程中遇到的问题给出,在大家遇到这类问题时,可以知道如何解决。

上面说了那么多,我们还是来看看如何从一个简单的例子入门吧。

JGroups的编码很简单,我们只需要编写一个发送端和一个接收端即可,发送端用来发送消息,接收端用来接收消息。

下面是发送端的示例代码:

public class Client {

private static JChannel channel = null;

//不管是发送端,还是接收端,都是从JChannel开始的。

public static void start()

{

String groupName = "pushserver2";

//群组名,一个JGroups群的唯一标示符。

try {

if(channel == null)

{

//创建一个通道

channel = new JChannel();

}

//加入一个群

channel.connect(groupName);

} catch (Exception e) {

close();

channel = null;

}

}

//发送方法

public static void send(byte[] message)

{

if(channel == null) start();

System.out.println("addr:"+channel.getAddressAsString());

Message msg=new Message(null, channel.getAddress(), message);

//第一个参数是接收方的地址,如果是null的话,表示是广//播,即群里所有接收方都会收到消息。

//第二个参数是发送方地址。

//这个类以后还会详细说到。

try {

channel.send(msg);

logger.debug("the notify server has already send themessage to the Transfer service.\nthe message is "+message);

} catch (Exception e) {

logger.error("send message: "+message+"failed!", e);

}

}

public static void close()

{

if(channel != null)

{

channel.close();

}

}

public static void main(String[] args) {

String str = "Hello,JGroups!";

Client2.send(str.getBytes());

}

}

以下是接收方代码:

public class Receiver extendsReceiverAdapter{

privatestatic JChannel channel = null;

publicstatic void start()

{

StringgroupName = "pushserver2";

try{

if(channel== null)

{

//创建一个通道

channel= new JChannel();

}

ReceiverAdapterreceiver = new Receiver();

//创建一个接收器

channel.setReceiver(receiver);

//加入一个群

channel.connect(groupName);

}catch (Exception e) {

channel= null;

}

}

@Override

public void receive(Message msg)

{

byte[]mgs = msg.getBuffer();

System.out.println(".......................................");

System.out.println("transmitserver received size: "+mgs.length);

System.out.println(newString(mgs));

System.out.println(".......................................");

}

publicstatic void main(String[] args) {

start();

}

}

要编译上面的代码,我们需要JGroups的jar包,可以到下面的网站下载:

http://sourceforge.net/projects/javagroups/files/

然后把代码所需要的类引入进来,可以编译了。

同时,我们也鼓励大家访问JGroups官网:

http://www.jgroups.org/

在上面,我们可以查看详细的文档,也可以查看源码。

下面,我们来看看上述代码的运行结果。

对于上述代码,我们先运行接收方代码,再运行发送方代码。

在发送方,我们得到如下的输出:

addr:WIN-HR4AJRNL7RQ-36341

在接收方,我们得到了如下的输出:

.......................................

transmit server received size: 14

Hello,JGroups!

.......................................

可以看到,JGroups的代码实现的确很简单。

有了这个简单的例子,我们的JGroups之行算是走了第一步。

读书人网 >软件架构设计

热点推荐