ZeroMQ(java)中组件间数据传输(Pipe的实现)

原创 2013年12月05日 13:53:45

在ZeroMQ(java)中,整个IO的处理流程都是分层来进行的,当然处于最下端的肯定是前面介绍过的poller以及StreamEngin了。。。。涉及到上层的话就还有session,以及socket,先用一张图来大概的描述一下整个层次关系吧。。



整个分层的结构大概就是这样吧,其中poller与StreamEngin是怎么交互的,这个就不说饿了吧,然后Session这个怎么与session之间交互呢,这个以后再说吧,其实在streamEngin里面有自己的session引用。。反正这里没啥意思。。主要就在与Session怎么与自己所属的Socket进行交互,当从最底层接收到数据之后,session如何交给上层的socket,让其来处理。。。这里就涉及到了Pipe,也就是session与自己所属的socket之间是通过pipe来进行数据传递的。。。

那么在具体的分析session与socket之前就来看看这个Pipe是怎么工作的吧,先来大概的看看它的类图:



这里可以看到Pipe继承自ZObject类型,那么可以知道Pipe可以发送,接受以及执行命令,同时也就意味着Pipe也需要由自己关联的IO线程才行,或者说有关联的mailbox。。。不过这个也不是强制的,以后再分析Socket的pipe的时候,就会发现它的pipe关联到socket自己的mailbox,但是socket的mailbox没有注册到任何的poller上面去,也就是它并没有在任何IO线程里执行,最后其实是在用户代码的线程中运行的。。。。好了。好像闲话说的比较多了。。用一张图来刻画一下Pipe是怎么运行的吧:



其实通过这张图形就已经将Pipe的运行原理基本描述出来了,pipe的两端都分别关联了两个YPipe(可以将其理解为队列)对象,例如左边将其中一个YPipe当做写端,那么在另外一边就将其看成是读端。。。

这里的YPipe对象可以将其理解为队列,至于说具体的实现,底层确实是队列,只不过是自己实现的,而且实现的还挺繁琐的,就不细说了,不过这里有向吐槽的地方,明明concurrent库中有无锁的队列ConcurrentLinkedList,在并发环境下有很好的性能,干嘛不在这个基础上进行扩展。。。。

这里另外还要看看在ZeroMQ中,也定义的有Pipe类型自己的事件回调,其定义如下:

    public interface IPipeEvents {
        void read_activated(Pipe pipe);  //有数据可以读取
        void write_activated(Pipe pipe);  //当前pipe有数据写
        void hiccuped(Pipe pipe);   //对面的pipe替换掉了读端,也就是当前需要替换写段的时候的回调
        void terminated(Pipe pipe);  //当前pipe停止的回调
    }

具体每个方法是干嘛用的注释应该说的很清楚了。。那么接下来来看看Pipe的两端是怎么进行交互的吧,首先看如何发送数据到pipe的另外一端:

    //从写端写数据局,发送给pipe的另外一端
    public boolean write (Msg msg_)  {
        if (!check_write ())
            return false;

        boolean more = msg_.has_more();
        outpipe.write (msg_, more);

        if (!more)
            msgs_written++;   //已经读取的msg的计数

        return true;
    }

其实这里直接就是在写端,将数据写到队列里面去就好了,那么如何通知对面当前有数据发送过来了呢,来看另外一个方法:

    //其实这里主要是给对面的pipe发送activate_read命令,表示它可以读了
    public void flush () {
        //  The peer does not exist anymore at this point.
        if (state == State.terminating)
            return;

        if (outpipe != null && !outpipe.flush ()) {
            send_activate_read (peer);  //向对面发送可以读取的命令
        } 
    }

这个,如果看了ZObject就应该很清楚了吧,直接给命令的另外一端发送activate_read类型的命令,那么这个命令最终将会被pipe的另外一端所关联的mailbox收到,从而对面的Pipe将会在其IO线程中执行命令,对于这个命令,进行的操作是process_activate_read方法,那么来看看Pipe中这个方法的的定义吧:

    //收到命令,表示底层的pipe有数据可以读取了,这里主要是要调用事件回调,通知上层的代码,pipe有数据可以读取了
    protected void process_activate_read () {
        if (!in_active && (state == State.active || state == State.pending)) {
            in_active = true;
            sink.read_activated (this);  //调用事件回调
        }
    }

这里其实就是调用当前的pipe的事件回调,来处理当前的pipe对象,其实也就是通知上层的代码,当前pipe有数据可以读了,让其进行处理。。。。

好了,那么到这里整个Pipe的运行原理就算比较的清楚了。。。

不过自己不太明白,在java中这种数据的传递明明很简单就可以实现,干嘛要搞的这么复杂。。。不过这里也有一个好处,就是将每一个对象的方法的执行都封闭在了自己的IO线程内部。。。也算是一种线程封闭原则的实现吧。。。其余的好处,好像没啥好处,而且真的觉得略繁琐。。。。

相关文章推荐

zeromq简介及各个通讯模式实例详解(附java实现)

Request-Reply模式 问答模式,使用REQ-REP套接字发送和接受消息是需要遵循一定规律的。客户端首先使用zmq_send()发送消息,再用zmq_recv()接收,如此循环。如果打乱了这个...

ZeroMQ(Java)使用个人小心得,这里Mark一下(适用于windows64bit及32bit)

首先,让我来介绍一下什么是ZMQ(全称:ZeroMQ): 官方: “ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加...

JAVA使用ZeroMQ优秀的使用(从0到1)

1.开始下载java需要的东西.    地址:http://download.csdn.net/detail/asfg5369/9800343 2.搭建环境()     2.1       下...

ZeroMQ:订阅-发布模式的java程序示例

ZeroMQ:订阅-发布模式的java程序示例  休息完了我们可以接着我们的旅程了,现在我们来验证下自己编译生成的东西是否能用, 具体怎么编译就请回顾我们的上期旅行http://blog.csdn...

ZeroMQ(java)之Requerst/Response模式

自己最开始是在cloud foundry中接触过消息服务器(nats),或者说是消息中间件,也算是初步知道了一个消息服务器对于分布式的网络系统的重要性,后来自己也曾想过在一些项目中使用它,尤其是在一些...

ZeroMQ(java)之Push/Pull模式

在ZeroMQ中并没有绝对的服务端与客户端之分,所有的数据接收与发送都是以连接为单位的,只区分ZeroMQ定义的类型,例如Response与Request,Publisher与Subscriber,P...

ZeroMQ(java)之Publish/Subscribe模式

前面的文章介绍了比较简单的Request/Subscribe模式, 这篇文章介绍更为经典的Publish/Subscribe通信模式用来ZeroMQ的实现,其通信方式如下图: ...

ZeroMQ 的java 插件

有java程序要用ZeroQM,从ZeroMQ的port里得到数据。在以前的VM里设置过,但是把程序移动到新的VM里就出现了Error: java.lang.UnsatisfiedLinkErr...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

ZeroMQ(java)之负载均衡

我们在实际的应用中最常遇到的场景如下: A向B发送请求,B向A返回结果。。。。 但是这种场景就会很容易变成这个样子: 很多A向B发送请求,所以B要不断的处理这...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZeroMQ(java)中组件间数据传输(Pipe的实现)
举报原因:
原因补充:

(最多只允许输入30个字)