文档章节

(转)ZeroMQ试用笔记之REQ & ROUTER

DEC_LIU
 DEC_LIU
发布于 2013/09/06 14:56
字数 1083
阅读 2075
收藏 5

zeromq的尝鲜笔记之一。内容包含ROUTER socket的理解介绍,一个小代码片段,以及czmq中处理消息帧的api的用法。

试用说白了就是用zeromq写套小东西。期间必然会遇到问题,笔记的目的无非就是记录问题,加深理解。而实际上我在记录的过程中也不断地修正了一些起初想当然的错误的理解。虽说已极力避免,但由于都是自己一人的理解,错误在所难免,希望有兴趣看的同学帮我指出。

背景

目标是依赖Zeromq实现一个支持并发的server端,接收多个client的请求,略作处理后返回响应。

client端是windows上的java程序。server端则是CentOS下的cpp程序。

实现

若直接用REQ-REP模式的话,需要注意到:REP端必须严格遵循recv,send,recv,send….的步骤,倘若REP端在recv后 需要一定时间的处理之后才能send,那么接下来的下一个REQ就得被迫等着了。所以从外部看,我们的REP的并发只有1。就跟下面这张图一样,步骤4的 消息必须等到步骤3之后才能被接收。

这可能是有些场景下必须的,但不是我想要的。因为我们需要并发。说白了就是我们要在步骤2的执行期间,把步骤4甚至接下来的5、6都做了。

ROUTER 正是基于这样的目的才被引入的。我们之前也有过介绍,但那个介绍在我看来更像是个guide翻译。这里再加上自己的理解细说一下。

REP之所以要按部就班,因为它如果不按部就班,就不知道把响应发回给哪里,所以它必须要同步地,先recv再send。

我们再来看ROUTER。它之所以可以不按部就班,是因为它收到REQ的消息时,在消息头上加入来源地址,然后再交给客户端。发送时,取出消息第一帧作为目标地址,将空帧之后的帧进行发送。

举例来说,app1通过REQ发送给通过ROUTER接收的app2。若app1发送的是

1 ["hello"]

,经由ROUTER的处理,app2应用层得到的消息将是

1 [app1's address|empty|"hello"]

对于app2,不能只关心业务数据”hello”,还需要将app1′s address缓存下来,用以响应的回复。比如,若app2要回复”world”,需要手动构造一个有三个frame的消息:

1 [app1's address|empty|"world"]

再把这个消息交给ROUTER socket进行send,这时ROUTER会将第一帧address取出作为目标地址——也就是的REQ端——,再将空帧之后的数据发出。所以最终REQ端收到响应为:

1 ["world"]

这些步骤看起来复杂,看看C代码怎么写。zeromq给我们提供了包装库czmq,利用它我们可以很方便地做到上述的过程。
这是代码片段。

1 void*receiver = zsocket_new(ctx, ZMQ_ROUTER);
2 zsocket_bind(receiver,"ipc:///tmp/0");
3  
4 ....
5  
6 //recv message
7 zmsg_t *msg = zmsg_recv(receiver);
8 if(!msg){
9     //error handle..
10     return;
11 }
12 zframe_t *address = zmsg_unwrap (msg);
13 zframe_t *frame = zmsg_first (msg);
14 zmsg_destroy (&msg);
15  
16 //do something, it make time some times...
17  
18 //make response message
19 zmsg_t *message = zmsg_new();
20 zframe_t* body = zframe_new("world",sizeof("world"));
21  
22 zmsg_push (message, body);
23 zmsg_wrap (message, address);
24  
25 zmsg_send (&message, receiver);
26 zmsg_destroy(&message);

需要说明的是czmq里的几个函数,万万不可用错。虽然有注释,但要用对这些api首先得搞清楚里面提到的first,front在message里是怎么个位置,为此我画了个图:

1 //  Pop frame off front of message, caller now owns frame
2 //  If next frame is empty, pops and destroys that empty frame.
3 zframe_t *
4     zmsg_unwrap (zmsg_t *self);
1 //  Return first frame in message, or null
2 zframe_t *
3     zmsg_first (zmsg_t *self);
1 //  Push frame to front of message, before first frame
2 void
3     zmsg_push (zmsg_t *self, zframe_t *frame);
1 //  Push frame to front of message, before first frame
2 //  Pushes an empty frame in front of frame
3 void
4     zmsg_wrap (zmsg_t *self, zframe_t *frame);

所以回头看代码片段,我们在构造响应消息时先push了一个填充着"world"的帧。再zmsg_wrap了一个填充着address的帧。
zmsg_wrap做了两个事情:1)在"world"之前放上address的帧; 2)在这个帧front放个空帧。

本文转载自:

DEC_LIU
粉丝 27
博文 18
码字总数 9469
作品 0
浦东
架构师
私信 提问
ZeroMQ 替换 HTTP 作为内部服务

这篇文章描述如何使用 ZeroMQ 作为 RPC 调用内部服务。对于公共的对外服务,HTTP 是经典的选择。但是在由许多小部件构成的系统中的内部服务 RPC,可能使用 ZeroMQ 代替 HTTP 更好。 总体上,...

oschina
2013/07/23
7.9K
3
高性能的通讯库-zeroMQ的几个高性能特征

这两天研究了一下zeroMQ,号称史上最好的通讯库,比rabbitMQ快很多,基于c语言开发的,实时流处理sorm的task之间的通信就是用的zeroMQ。 zeroMQ在使用模式上支持多种,有req-reply,publish...

天下杰论
2014/10/08
510
0
了解saltstack的通信协议zeromq(一)

学了saltstack有一段时间了,说实话,对于一个python爱好者来说salt源代码真是一个宝藏啊。于是乎去看了源代码,发现所有问题都卡在了底层通信上,在看saltstack之前都不知道有一个这么好的z...

liuping0906
2018/07/02
0
0
[架构] ZeroMQ 深度探索(一)

序 最初认识 ZeroMQ 是被它的名号所吸引,最近在一个高性能中间件的项目中用到了 ZeroMQ,对这个号称“史上最快的消息队列”有了更深层次的了解。如果我们仅仅把 ZeroMQ 看作是一个消息队列,...

长平狐
2013/07/01
8.1K
0
ZeroMQ一次send较大的数据,如何获取其传输进度?

ZeroMQ一次send较大的数据,如何获取其传输进度?(ZMQ_REQ模式下)万分感谢!

casinozyz
2018/05/27
650
0

没有更多内容

加载失败,请刷新页面

加载更多

反编译9.png图片还原

本文链接:https://blog.csdn.net/a1140778530/article/details/10528507 经常反编译apk文件找资源,9.png的文件处理起来很麻烦。 最近使用Ant自动编译打包app时,从别处搜罗来的9.png文件导...

shzwork
8分钟前
2
0
Shell脚本应用 – for、while循环语句

一、for循环语句 在实际工作中,经常会遇到某项任务需要多次执行的情况,而每次执行时仅仅是处理的对象不一样,其他命令相同。例如:根据通讯录中的姓名列表创建系统账号等情况。 当面对各种...

linux-tao
8分钟前
2
0
RPA风潮下企业财务工作模式的变革

RPA(机器人流程自动化)在财务领域的应用,正给企业财务带来前所未有的改变。 前RPA时代,财务领域面临的痛点 在RPA机器人应用之前,企业财务工作进程的推进,主要通过财务人员人工操作或信...

UiBot
13分钟前
2
0
Hive之命令行修改表注释

最近遇到一个需求,在不重建表的情况下,修改表的注释,hive有没有类似关系型数据库的SQL命令来修改呢,找了下,亲测有效,如下List-1 List-1 hive>use your_schemahvie>ALTER TABLE tabl...

克虏伯
13分钟前
2
0
是什么,它的作用是什么

在HTML文档的首部往往会有这么一句话<!DOCTYPE html>,许多时候我们忽视了它的存在,它实际上是一个声明,告诉浏览器用哪种HTML版本的规范来解读HTML文档。 尽管我们不给出这句声明浏览器照样...

前端老手
19分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部