史上最快消息内核——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"); ????int request_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); ????return 0; } |
服務端(接收客戶端的消息,返回“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); ????} ????return 0; } |
一個套接字相關的調用都沒有,一個網絡程序就寫好了,生活真美好啊。
與其他的消息隊列相比,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版),設計上還有一點點小缺陷,比如不能得到客戶端的IP,丟消息等。不過,開發很活躍,很有潛力。另外,ZeroMQ配合Protocol buffer使用真是絕了。
官方的教程寫的非常詳細:http://zguide.zeromq.org/chapter:all大家可以去看看。
相關文章:
轉自:http://blog.dccmx.com/2011/02/zeromq/
轉載于:https://www.cnblogs.com/viviancc/archive/2012/04/24/2468391.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的史上最快消息内核——ZeroMQ的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 航海王燃烧意志有破解版吗
- 下一篇: 换机助手如何使用