NetMQ(四): 推拉模式 Push-Pull
ZeroMQ系列 之NetMQ
一:zeromq简介
二:NetMQ 请求响应模式 Request-Reply
三:NetMQ 发布订阅模式 Publisher-Subscriber
四:NetMQ 推拉模式 Push-Pull
NetMQ 推拉模式 Push-Pull
1:简介
推拉模式,也叫 管道模式”Parallel Pipeline”。想象一下这样的场景,如果需要统计各个机器的日志,我们需要将统计任务分发到各个节点机器上,最后收集统计结果,做一个汇总。PipeLine比较适合于这种场景,他的结构图,如图1所示

图1 官方图
Ventilator,在管道中生产任务;
Worker ,处理任务;
Sink,收集Worker处理的结果。
2:案例
下面有三个对象Ventilator 消息分发者,Worker 消息处理者,Sink 接受Worker处理消息后返回的结果,耗时的计算处理工作是交给Worker的,如果开多个Worker.exe,可以提升处理速度,Worker的最终目的是分布式计算,部署到多台PC上面,把计算工作交给他们去做(在分布式爬虫上面,每个Worker相当于一个爬虫)。
下面案例结构,如图2所示:

图2
源码:
Ventilator
static void Main(string[] args)
{
// Task Ventilator
// Binds PUSH socket to tcp://localhost:5557
// Sends batch of tasks to workers via that socket
Console.WriteLine("====== VENTILATOR ======");
//socket to send messages on
using (NetMQSocket sender = new DealerSocket())
{
sender.Bind("tcp://*:5557");
using (var sink = new DealerSocket())
{
sink.Connect("tcp://localhost:5558");
Console.WriteLine("Press enter when worker are ready");
Console.ReadLine();
//the first message it "0" and signals start of batch
//see the Sink.csproj Program.cs file for where this is used
Console.WriteLine("Sending start of batch to Sink");
sink.SendFrame("0");
Console.WriteLine("Sending tasks to workers");
//initialise random number generator
Random rand = new Random(0);
//expected costs in Ms
int totalMs = 0;
//send 100 tasks (workload for tasks, is just some random sleep time that
//the workers can perform, in real life each work would do more than sleep
for (int taskNumber = 0; taskNumber < 100; taskNumber++)
{
//Random workload from 1 to 100 msec
int workload = rand.Next(0, 100);
totalMs += workload;
Console.WriteLine("Workload : {0}", workload);
sender.SendFrame(workload.ToString());
}
Console.WriteLine("Total expected cost : {0} msec", totalMs);
Console.WriteLine("Press Enter to quit");
Console.ReadLine();
}
}
}
Worker
static void Main(string[] args)
{
// Task Worker
// Connects PULL socket to tcp://localhost:5557
// collects workload for socket from Ventilator via that socket
// Connects PUSH socket to tcp://localhost:5558
// Sends results to Sink via that socket
Console.WriteLine("====== WORKER ======");
//socket to receive messages on
using (var receiver = new DealerSocket())
{
receiver.Connect("tcp://localhost:5557");
//socket to send messages on
using (var sender = new DealerSocket())
{
sender.Connect("tcp://localhost:5558");
//process tasks forever
while (true)
{
//workload from the vetilator is a simple delay
//to simulate some work being done, see
//Ventilator.csproj Proram.cs for the workload sent
//In real life some more meaningful work would be done
string workload = receiver.ReceiveString();
//simulate some work being done
Thread.Sleep(int.Parse(workload));
//send results to sink, sink just needs to know worker
//is done, message content is not important, just the precence of
//a message means worker is done.
//See Sink.csproj Proram.cs
Console.WriteLine("Sending to Sink");
sender.SendFrame(string.Empty);
}
}
}
}
Sink
static void Main(string[] args)
{
// Task Sink
// Bindd PULL socket to tcp://localhost:5558
// Collects results from workers via that socket
Console.WriteLine("====== SINK ======");
//socket to receive messages on
using (var receiver = new DealerSocket())
{
receiver.Bind("tcp://localhost:5558");
//wait for start of batch (see Ventilator.csproj Program.cs)
var startOfBatchTrigger = receiver.ReceiveString();
Console.WriteLine("Seen start of batch");
//Start our clock now
Stopwatch watch = new Stopwatch();
watch.Start();
for (int taskNumber = 0; taskNumber < 100; taskNumber++)
{
var workerDoneTrigger = receiver.ReceiveString();
if (taskNumber % 10 == 0)
{
Console.Write(":");
}
else
{
Console.Write(".");
}
}
watch.Stop();
//Calculate and report duration of batch
Console.WriteLine();
Console.WriteLine("Total elapsed time {0} msec", watch.ElapsedMilliseconds);
Console.ReadLine();
}
}
效果图:
处理一个Ventilator任务,可以使用数量不同的worker:
一个worker:
在我本地计算机上,耗时 5566 mesc

二个worker:
在我本地计算机上,耗时2917 mesc

三个worker:
在我本地计算机上,耗时2031 msec

3:总结
- 使用的NetMQ版本是3.3.3.1,实例化DealerSocket,来创建socket。
- Ventilator分发工作到不同的Worker,实现负载均衡。
- Ventilator和Sink是静态部分,Worker是动态的。开启更多的Worker,理论上完成工作更快。
- Sink收集Worker处理的结果.
4:下载
NetMQ(四): 推拉模式 Push-Pull的更多相关文章
- ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习
转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...
- 消息队列-推/拉模式学习 & ActiveMQ及JMS学习
一种分类是推和拉 . 还有一种分类是 Queue 和 Pub/Sub . 先看的这一篇:http://blog.csdn.net/heyutao007/article/details/50131089 ...
- RabbitMQ入门_03_推拉模式
我们知道,消费者有两种方式从消息中间件获取消息: 推模式:消息中间件主动将消息推送给消费者 拉模式:消费者主动从消息中间件拉取消息 推模式将消息提前推送给消费者,消费者必须设置一个缓冲区缓存这些消息. ...
- 实战ZeroMQ的PUSH/PULL推拉模式
原文地址: http://ju.outofmemory.cn/entry/235976
- 微博feed系统的推(push)模式和拉(pull)模式和时间分区拉模式架构探讨
sns系统,微博系统都应用到了feed(每条微博或者sns里的新鲜事等我们称作feed)系统,不管是twitter.com或者国内的新浪微博,人人网等,在各种技术社区,技术大会上都在分享自己的feed ...
- [转] 消息系统该Push/Pull模式分析
信息推拉技术简介 “智能信息推拉(IIPP)技术”是在网上信息获取技术中加入了智能成份,从而有助于用户在海量信息中高效.及时地获取最新信息,提高了信 息系统主动信息服务的能力.如果引入基于IIPP的主 ...
- 理解bootstrap的列偏移offset 和 推拉push/pull的区别?
参考: http://www.cnblogs.com/jnslove/p/5430481.html & https://blog.csdn.net/hly_coder/article/deta ...
- 脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)
本文原作者阮一峰,作者博客:ruanyifeng.com. 1.前言 新一代HTTP/2 协议的主要目的是为了提高网页性能(有关HTTP/2的介绍,请见<从HTTP/0.9到HTTP/2:一文读 ...
- RocketMQ(一):推拉消费模型客户端实践
消息中间件是为解耦生产者和消费者的目的,三大服务点:解耦.异步.削峰. 现在的的互联网系统中,mq已经必备基础设施了,我们已明显感觉它的必要性与强大.然而,它的本质是啥?存储转发系统罢了! MQ有很多 ...
随机推荐
- [Android]快捷键
小技巧,快捷键 快捷键创建资源: Windows下是 alt+enter; Mac下是Option+enter 创建构造函数,Get/Set:Command+N,Windows环境中Alt + Ins ...
- webstorm 更改默认服务器端口
File ->Settings Build,Execution,Deployment->Debugger 如下图 找到Debugger
- Web.xml详解(转)
这篇文章主要是综合网上关于web.xml的一些介绍,希望对大家有所帮助,也欢迎大家一起讨论. ---题记 一. Web.xml详解: (一) web.xml加载过程(步骤) 首 ...
- MATLAB-RSP 随笔
1.Getting Started with Signal Analyzer App 161216 (1) 在命令行中输入:signalAnalyzer. (2)在工作空间中选择要分析的信号
- js作用域
一.js没有块级作用域 在c,java等语言中花括号里的代码都有自己的作用域,而js花括号没有块级作用域,经常会导致一些困惑,不明所以.例如: console.info(color); if(true ...
- lcov和gcov的使用错误
编译使用的gcc版本和gcov的版本对不上的话,使用lcov和gcov的时候会报错 lcov的错误: [xx@localhost XXX]$ lcov --capture --directory co ...
- mysql中distinct的用法
本事例实验用表task,结构如下 MySQL> desc task; +-------------+------------+------+-----+-------------------+- ...
- js事件技巧方法整合
window.resizeTo(800,600); //js设置浏览器窗口尺寸 window.open (function(){ resizeTo(640,480);//设置浏览器窗口尺寸 moveT ...
- 消除左递归c语言文法
<程序> -〉 <外部声明> | <函数定义><外部声明> -〉<头文件> | <变量> | <结构体> <头 ...
- JS学习:第二周——NO.1回调函数
[回调函数] 定义:把一个函数的定义阶段,作为参数,传给另一个函数: 回调函数调用次数,取决于条件: 回调函数可以传参: 回调函数可以给变this指向,默认是window: 回调函数没有返回值,for ...