[转]史上最快消息内核——ZeroMQ

标签: 消息 内核 zeromq | 发表时间:2011-08-02 10:16 | 作者:heiyeshuwu 乾
出处:http://blog.csdn.net/heiyeshuwu


作者:dccmx
来源:http://blog.dccmx.com/2011/02/zeromq/ 


ZeroMQ是一个很有个性的项目,它原来是定位为“史上最快消息队列”,所以名字里面有“MQ”两个字母,但是后来逐渐演变发展,慢慢淡化了消息队列的身影,改称为消息内核,或者消息层了。从网络通信的角度看,它处于会话层之上,应用层之下,有了它,你甚至不需要自己写一行的socket函数调用就能完成复杂的网络通信工作。

借用官方的例子:

客户端(发送N个“Hello”消息到服务端,接受回应):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//
//  Hello World client
//  Connects REQ socket to tcp://localhost:5555
//  Sends "Hello" to server, expects "World" back
//
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
  
int main () {
    void*context = zmq_init (1);
  
    //  Socket to talk to server
    printf("Connecting to hello world server...\n");
    void*requester = zmq_socket (context, ZMQ_REQ);
    zmq_connect (requester,"tcp://localhost:5555");
  
    intrequest_nbr;
    for(request_nbr = 0; request_nbr != 10; request_nbr++) {
        zmq_msg_t request;
        zmq_msg_init_data (&request,"Hello", 6, NULL, NULL);
        printf("Sending request %d...\n", request_nbr);
        zmq_send (requester, &request, 0);
        zmq_msg_close (&request);
  
        zmq_msg_t reply;
        zmq_msg_init (&reply);
        zmq_recv (requester, &reply, 0);
        printf("Received reply %d: [%s]\n", request_nbr,
            (char*) zmq_msg_data (&reply));
        zmq_msg_close (&reply);
    }
    zmq_close (requester);
    zmq_term (context);
    return0;
}


服务端(接收客户端的消息,返回“World”给客户端):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//
//  Hello World server in C++
//  Binds REP socket to tcp://*:5555
//  Expects "Hello" from client, replies with "World"
//
#include <zmq.hpp>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
  
int main () {
    //  Prepare our context and socket
    zmq::context_t context (1);
    zmq::socket_t socket (context, ZMQ_REP);
    socket.bind ("tcp://*:5555");
  
    while(true) {
        zmq::message_t request;
  
        //  Wait for next request from client
        socket.recv (&request);
        printf("Received request: [%s]\n",
            (char*) request.data ());
  
        //  Do some 'work'
        sleep (1);
  
        //  Send reply back to client
        zmq::message_t reply (6);
        memcpy((void*) reply.data (), "World", 6);
        socket.send (reply);
    }
    return0;
}

一个套接字相关的调用都没有,一个网络程序就写好了,生活真美好啊。

与其他的消息队列相比,ZeroMQ有以下一些特点

1.点对点无中间节点。

传统的消息队列都需要一个消息服务器来存储转发消息。而ZeroMQ则放弃了这个模式,把侧重点放在了点对点的消息传输上,并且(试图)做到极致。以为消息服务器最终还是转化为服务器对其他节点的点对点消息传输上。ZeroMQ能缓存消息,但是是在发送端缓存。ZeroMQ里有水位设置的相关接口来控制缓存量。当然,ZeroMQ也支持传统的消息队列(通过zmq_device来实现)。

2.强调消息收发模式。

在点对点的消息传输上ZeroMQ将通信的模式做了归纳,比如常见的订阅模式(一个消息发多个客户),分发模式(N个消息平均分给X个客户)等等。下面是目前支持的消息模式配对,任何一方都可以做为服务端。

  • PUB and SUB
  • REQ and REP
  • REQ and XREP
  • XREQ and REP
  • XREQ and XREP
  • XREQ and XREQ
  • XREP and XREP
  • PUSH and PULL
  • PAIR and PAIR

3.以统一接口支持多种底层通信方式(线程间通信,进程间通信,跨主机通信)。

如果你想把本机多进程的软件放到跨主机的环境里去执行,通常要将IPC接口用套接字重写一遍。非常麻烦。而有了ZeroMQ就方便多了,只要把通信协议从"ipc:///xxx"改为"tcp://*.*.*.*:****"就可以了,其他代码通通不需要改,如果这个是从配置文件里读的话,那么程序就完全不要动了,直接复制到其他机器上就可以了。以为ZeroMQ为我们做了很多。

4.异步,强调性能。

ZeroMQ设计之初就是为了高性能的消息发送而服务的,所以其设计追求简洁高效。它发送消息是异步模式,通过单独出一个IO线程来实现,所以消息发送调用之后不要立刻释放相关资源哦,会出错的(以为还没发送完),要把资源释放函数交给ZeroMQ让ZeroMQ发完消息自己释放。

目前ZeroMQ还不是非常成熟(本文写作时最新版是2.0.10版),设计上还有一点点小缺陷。不过,开发很活跃,很有潜力。另外,ZeroMQ配合Protocol buffer使用真是绝了。

官方的教程写的非常详细:http://zguide.zeromq.org/chapter:all大家可以去看看。




相关其他参考文档:

http://blog.codingnow.com/2011/02/zeromq_message_patterns.html

http://zsp.iteye.com/blog/377588

http://www.cppblog.com/woaidongmao/archive/2011/04/04/143409.aspx

http://www.infoq.com/cn/news/2010/09/introduction-zero-mq



作者:heiyeshuwu 发表于2011-8-2 3:16:06 原文链接
阅读:838 评论:0 查看评论

相关 [消息 内核 zeromq] 推荐:

[转]史上最快消息内核——ZeroMQ

- 乾 - heiyeluren的blog(黑夜路人的开源世界)
来源:http://blog.dccmx.com/2011/02/zeromq/ . ZeroMQ是一个很有个性的项目,它原来是定位为“史上最快消息队列”,所以名字里面有“MQ”两个字母,但是后来逐渐演变发展,慢慢淡化了消息队列的身影,改称为消息内核,或者消息层了. 从网络通信的角度看,它处于会话层之上,应用层之下,有了它,你甚至不需要自己写一行的socket函数调用就能完成复杂的网络通信工作.

消息中间件的技术选型心得-RabbitMQ、ActiveMQ和ZeroMQ

- - haohtml's blog
RabbitMQ、ActiveMQ和ZeroMQ都是极好的消息中间件,但是我们在项目中该选择哪个更适合呢. 下面我会对这三个消息中间件做一个比较,看了后你们就心中有数了. RabbitMQ是AMQP协议领先的一个实现,它实现了代理(Broker)架构,意味着消息在发送到客户端之前可以在中央节点上排队.

ZeroMQ(java)中监控Socket

- - CSDN博客架构设计推荐文章
基本上ZeroMQ(java)中基本的代码都算是过了一遍了吧,不过觉得它在日志这一块貌似基本没有做什么工作,也就是我们通过日志来知道ZeroMQ都发生了什么事情. 而且由于ZeroMQ中将连接的建立和重连接都进行了隔离,用户不需要做什么事情来维护连接,当然这样做的好处是使程序员的编码工作变少了,但是当然也有不好的地方,那就是用户失去了对ZeroMQ整个运行阶段的控制.

[转][转]ZeroMQ 深度探索

- - heiyeluren的blog(黑夜路人的开源世界)
最初认识 ZeroMQ 是被它的名号所吸引,最近在一个高性能中间件的项目中用到了 ZeroMQ,对这个号称“史上最快的消息队列”有了更深层次的了解. 如果我们仅仅把 ZeroMQ 看作是一个消息队列,那就完全搞错了,ZeroMQ 是一套智能传输层协议,它不仅为开发者提供了强大的开发包,还包含了一套很棒的通信协议的实现,更值得一提是,它对分布式系统开发有着相当独到的见解,绝对值得我们好好学习.

ZeroMQ--使用jzmq进行编程

- - 编程语言 - ITeye博客
如果没有安装libtool、libuuid-devel则需要先安装,否则安装失败. 出现java.lang.UnsatisfiedLinkError: /usr/local/lib/libjzmq.so.0.0.0: libzmq.so.1: cannot open shared object file: No such file or directory异常 .

ZeroMQ(java)入门之Requerst/Response模式

- - CSDN博客架构设计推荐文章
自己最开始是在cloud foundry中接触过消息服务器(nats),或者说是消息中间件,也算是初步知道了一个消息服务器对于分布式的网络系统的重要性,后来自己也曾想过在一些项目中使用它,尤其是在一些分布式的环境下,可以极大的方便整个系统的实现. 在中间通过一个消息中间件,可以很方便的将各个woker的数据发送到最终的统计服务器来做数据的统计,从而减少很多在网络通信中会消耗的编程时间.

zmq-rpc:基于zeromq网络层编写的protobuf RPC框架

- Shengbin - codedump
阅读过zmq的代码之后,感觉这个网络层是我目前见过最高效的–线程之间使用lockfree的消息队列保存消息,可以启动多个I/O线程分担压力等等特性.于是决定基于它写一个protobuf RPC的框架.. 另外,这里使用的protobuf是旧版本2.3.0,新版本2.4.1的生成的RPC service接口跟原来不太一致,暂时还没有去研究它.BTW,升级版本之后导致原来的接口发生变化这是一个很操蛋的事情..

为什么我希望用C而不是C++来实现ZeroMQ

- - 博客 - 伯乐在线
开始前我要先做个澄清:这篇文章同Linus Torvalds这种死忠C 程序员吐槽C++的观点是不同的. 在我的整个职业生涯里我都在使用C++,而且现在C++依然是我做大多数项目时的首选 编程语言. 自然的,当我从2007年开始做 ZeroMQ( ZeroMQ项目主页)时,我选择用C++来实现.

消息两则

- 藏书人 - 李志官方博客
1,经过深思熟虑,我放弃了十月份做个人小巡演的计划,全心全意投入跨年音乐会的准备工作. 如不出意外,12月31日南京见. 2,如果不出意外,第六张专辑会在十一之前发布. 经过深思熟虑,我决定不做实体,直接放到官网提供下载,能者多劳,愿者给钱. 3,当然对我而言,意外是常态.

周一消息树

- 水御龙神 - 1416 教室
每一个光鲜的封面,都饱含美术编辑的”血泪“和杂志主编的“阴谋”——今天的消息树让我们将掀开封面往里瞅瞅. 最新一期的美国新闻周刊封面,实在让人有点儿难以置信. 优雅的戴安娜王妃突然出现在二十一世纪的街头,旁边是她的儿媳妇Kate,但仔细看,她却不是当年的王妃,变老了,变丑了——这是新闻周刊编辑们想象中的一个五十岁的女人的样子.