ZeroMQ的几种模式和使用场景

ZeroMQ也看了几天了,感觉这个库就是为我而生的,一直很讨厌封装底层socket,这个库的出现,对于通信的基础工作减轻了很多。ZeroMQ一共有以下几种模式:

  • PUB - SUB
  • REQ - REP
  • REQ - ROUTER
  • DEALER - REP
  • DEALER - ROUTER
  • DEALER - DEALER
  • ROUTER - ROUTER
  • PUSH - PULL
  • PAIR - PAIR

接下来我会按照我的理解逐个进行介绍,同时每种模式给一个实际工作中的例子。

push/pull模式

该模式最少由三个进程或线程组成,最上面是任务生成端,例如游戏服务器或者前端服务器,获取到需要计算或从不同io设备获取数据的任务。

中间三个worker用来具体干活,可以无限扩展。每个worker收到数据处理后发给Sink。

数据的流动是从vert到worker,worker处理后还给sink

vent====>worker====>sink

有一点需要注意的是,vent给worker发布任务是采用的轮训分配,也就是说每个worker获得的任务量是一样的,即使其中一个worker处理很慢,也不能少获得任务。因此这个模式主要用于worker工作量差不多大小的任务。例如从读写分离的集群redis中获取数据,每个worker从指定的一个读中获取信息。

ROUTER-DEALER模式

首先需要明确一点,向ROUTER发送消息,ZeroMQ会自动带上消息来源帧,同时由ROUTER发送出去的消息,需要手动带上目标id,这个id一般通过zmq_setsockopt进行定义:

如果ROUTER再向其他ROUTER发送消息,还会包一层包含地址来源的帧:

这样就一直可以查到消息的来源,每个经过ROUTER的消息,会被ROUTER放到最上面的表示,响应的,ROUTER收到的每个消息,第一帧一定是发送数据的addr。

ROUTER-DEALER本身可以演变以下几种模式:

  • ROUTER-DEALER
  • ROUTER-REQ
  • ROUTER-REP

这几种模式同时意味着,ROUTER可以同时连接这三种WORKER。

1.ROUTER-DEALER

ROUTER-DEALER是最简单的模型,一个ROUTER可以连接多个DEALER,每个DEALER只处理自己的消息。而ROUTER通过s_sendmore (client, "A");
或者
s_sendmore (client, "B");
来指定DEALER,然后是任务
s_send (client, "This is the workload");
将完整消息发给指定的DEALER,而DEALER是通过
zmq_setsockopt (worker, ZMQ_IDENTITY, "B", 1)
定义自己的id。这样在s_send 的时候,每个DEALER会收到指定给自己处理的消息。

这块有个伏笔,是之前图片上有一个空帧,但是这里只发送了id和数据,并没有发空帧数。实际上在ROUTER-DEALER模式下,那个空帧是可有可无的,这个我们最后再说。

2.ROUTER-REQ

ROUTER-REQ比ROUTER-DEALER灵活一些,因为REQ不像DEALER只有被动接受数据的能力,REQ可以主动告诉ROUTER我很闲,可以把数据发给我。这样ROUTER就能够使用最近最少使用算法(LRU)路由了,ROUTER发出的请求会让等待最久的REQ来处理。

worker端口代码如下,即使启动100个worker,核心代码也如下所示:

while (1) {
	    // 告诉ROUTER我已经准备好了
        s_send(worker, "ready");
 
        // 从ROUTER中获取工作,直到收到结束的信息
        char *workload = s_recv(worker);
        int finished = (strcmp(workload, "END") == 0);
        free(workload);
        if (finished) {
            printf("Processed: %d tasks\n", total);
            break;
        }
        total++;
 
        // 随机等待一段时间
        s_sleep(randof(1000) + 1);
    }

ROUTER-REQ模式最棒的地方是实现了基本的负载均衡,支持worker的横向扩展,不像PUSH - PULL中,PULL有概率一直收到最耗时的工作;而基于LRU算法的ROUTER-REQ中,REQ如果一直没有忙完,就不会收到新的工作。

 

 

 

 

 

 

空msg只是为了和rep以及req模型兼容,如果只是router和dealer模型则不需要这个空的分割消息。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值