ZeroMQ之Push与Pull (Java)
本系列文章均转自:http://blog.csdn.net/kobejayandy/article/details/20163431
在ZeroMQ中并没有绝对的服务端与客户端之分,所有的数据接收与发送都是以连接为单位的,只区分ZeroMQ定义的类型,例如Response与Request,Publisher与Subscriber,Push与Pull等。。。
例如在前面我们最开始的Response/Request模式,因为只有一个Response端,而有多个Request端,所以我们选择在Response端调用bind方法来建立监听,而在Request端调用connect方法与Response端建立连接。。。因此根据以前常用的概念,可以简单的将Response理解为服务端,将Request理解为客户端。。。。
这种状态下,整个系统大概用下面的图形来形容:
这里因此按照我们常规的区分方法,将建立监听的叫做服务端,发起连接的叫做客户端,但其实呢,在ZeroMQ这种按照监听的方式来区分是不成立的。。。将上图的网络构建变成如下这个样子:
上图的网络结构中,在Request端建立监听,而在Response发起与Request端的连接,这样,request同样可以发送请求到Response端。。。
其实说这么多无非就像强调:在ZeroMQ中,不要用常规的server/client模式来对组件进行分类,而应该采用ZeroMQ中定义的类型(Request,Response,Push,Pull)。
好了,接下来回到Push/Pull模式,这算是非常经典的了吧,Push产生消息,Pull角色来拿消息。。。甚至可以用生产者/消费者模型来对应。。。应用场景就非常的广泛了。。。最典型的应用场景就是任务分发。。。
在ZeroMQ中根据Push与Pull角色各自的数量又定义了一些比较有趣的名词:
(1)parallel pipeline,并行流水线,这种情况下是一个push,多个pull,可以理解为一个push不断的产生任务,并将这些任务分发给pull角色。。。如下图:
在这种网络结构中,manager不断的将任务分发给worker,要实现这种通信,在ZeroMQ中就直接用Push/Pull就可以了,代码也很简单,首先是Manager端(Push):
- package pushpull13;
- import org.zeromq.ZMQ;
- public class Push {
- public static void main(String args[]) {
- ZMQ.Context context = ZMQ.context();
- ZMQ.Socket push = context.socket(ZMQ.PUSH);
- push.bind("ipc://fjs");
- for (int i = ; i < ; i++) {
- push.send("hello".getBytes());
- }
- push.close();
- context.term();
- }
- }
代码很简单吧,这里建立的是PUSH类型的socket,然后循环一千万次,给建立连接的worker发送数据,那么接下来来看看Worker(Pull)部分的代码:
- package pushpull13;
- import java.util.concurrent.atomic.AtomicInteger;
- import org.zeromq.ZMQ;
- public class Pull {
- public static void main(String args[]) {
- final AtomicInteger number = new AtomicInteger();
- for (int i = ; i < ; i++) {
- new Thread(new Runnable(){
- private int here = ;
- public void run() {
- // TODO Auto-generated method stub
- ZMQ.Context context = ZMQ.context();
- ZMQ.Socket pull = context.socket(ZMQ.PULL);
- pull.connect("ipc://fjs");
- //pull.connect("ipc://fjs");
- while (true) {
- String message = new String(pull.recv());
- int now = number.incrementAndGet();
- here++;
- if (now % == ) {
- System.out.println(now + " here is : " + here);
- }
- }
- }
- }).start();
- }
- }
- }
这里建立了5个worker,建立于与manager的连接,这里可能就会涉及到一个问题,manager是怎么将数据分发给这5个woker的呢,这里由于还没有看过实现代码,所以不知道这里具体是怎么个策略,不过后来测试数据之后发现各个worker之间收到的数量相差不大,可以猜测大概是轮询发送的。。。。
好了,到这里整个所谓的并行流水线的网络构建就算是差不多了。。。那么接下来来看另外一种,这里Push与Pull之间的对应关系是多个Push角色对应一个Pull角色,在ZeroMQ中,给这种结构取的名叫做公平队列,结构如下图:
这里也就是说将Pull角色理解为一个队列,各个Push角色不断的向这个队列中发送数据。。。这种结构应用场景也很广泛吧,例如分布式的数据统计啥的。。。
好了,来看看实现代码形式吧,先来看看Push:
- package pushpull31;
- import org.zeromq.ZMQ;
- public class Push {
- public static void main(String args[]) {
- for (int j = ; j < ; j++) {
- new Thread(new Runnable(){
- public void run() {
- // TODO Auto-generated method stub
- ZMQ.Context context = ZMQ.context();
- ZMQ.Socket push = context.socket(ZMQ.PUSH);
- push.connect("ipc://fjs");
- for (int i = ; i < ; i++) {
- push.send("hello".getBytes());
- System.out.println(i);
- }
- push.close();
- context.term();
- }
- }).start();;
- }
- }
- }
由于这部分push与pull的关系是多对一,所以选择在pull端建立监听,让push端来连接pull端。。。代码还是很简单的吧。。。
不过这里有一个比较有意思的现象,加入我们先运行push端,而这个时候pull端并没有运行的话,会发现send方法也会被执行,只不过执行一会以后就阻塞了,这里可以猜测,ZeroMQ的push端是先将数据写到了一个缓冲区,然后数据是从缓冲区中写到已经建立好连接的pull端的,当然这个只是猜测,具体是什么样子的以后看看源码的实现就知道了。。。。
好了,接下来来看看Pull端的代码实现吧:
- package pushpull31;
- import org.zeromq.ZMQ;
- public class Pull {
- public static void main(String args[]) {
- ZMQ.Context context = ZMQ.context();
- ZMQ.Socket pull = context.socket(ZMQ.PULL);
- pull.bind("ipc://fjs");
- int number = ;
- while (true) {
- String message = new String(pull.recv());
- number++;
- if (number % == ) {
- System.out.println(number);
- }
- }
- }
- }
这里够简单吧,建立一个连接,然后循环里不断的接收数据就好了。。。
好了,到这里Push/Pull中的一对多与多对一的网络结构就算是讲完了吧,其实还有一种多对多的结构。。不过意思都差不多吧。。。。。就不具体弄出来了。。
ZeroMQ之Push与Pull (Java)的更多相关文章
- Push or Pull?
采用Pull模型还是Push模型是很多中间件都会面临的一个问题.消息中间件.配置管理中心等都会需要考虑Client和Server之间的交互采用哪种模型: 服务端主动推送数据给客户端? 客户端主动从服务 ...
- Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突
Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突 这篇是接着上篇分布式版本库--Windows下G ...
- Nginx-rtmp模块实现流媒体play、push、pull功能
官方wiki:https://github.com/arut/nginx-rtmp-module#readme Nginx rtmp 功能特点 1. 支持音视频直播 2. 支持flv/mp4视 ...
- 【Bootstrapt】offset、push、pull
实现方式的区别: col-md-offset-*,是利用margin-left实现的,col-md-push-*/col-md-pull-*是利用相对定位实现的. 效果的区别: col-md-offs ...
- git push和pull如何解决冲突!!!精品
多人合作完成项目时,git push 和 pull经常会发生冲突,根本原因就是远程的东西和本地的东西长的不一样,以下步骤能完美解决所有冲突!(先查看一下分支(git branch),确认没错再进行下面 ...
- 实战ZeroMQ的PUSH/PULL推拉模式
原文地址: http://ju.outofmemory.cn/entry/235976
- oschina代码仓库远程push,pull免密实操总结
刚做项目,用到开源中国(oschina)的git仓库,一个多月一直在痛苦的反复输密码的过程中度过.中间配置过几次免密登录,但总是时而登的上去,时而不行,大多数情况不行.近几日项目做完了,正好有空把这个 ...
- adb push和pull使用
1.运行cmd> 进入adb.exe目录 2.>adb connect ip 3.>adb remount 4.>adb push 本地apk全路径 /system/app/ ...
- git向gitHub上push和pull数据.
1.在gitHub上首先建立仓储.这个过程就不在啰嗦了. 2.注意上图中右下角的https,ssh等东西. 3.向git上传的工具特别多.我这里用的cygwin. 至于cygwin自己到网上去下载.安 ...
随机推荐
- [wikioi 1519]过路费(最小生成树+树链剖分)
题目:http://www.wikioi.com/problem/1519/ 题意:给你一个连通的无向图,每条边都有权值,给你若干个询问(x,y),要输出从x到y的路径上边的最大值的最小值 分析:首先 ...
- [USACO2006][poj3182]The Grove(巧妙的BFS)
题目:http://poj.org/problem?id=3182 题意:一个棋盘中间有一个联通块,给你一个起点让你从起点开始绕联通块外围一圈并回到起点,求最小步数. 分析: 首先根据数据的范围比较小 ...
- shell编程之基础
1.初探shell #!/bin/bash echo -e 'hello \nworld' 执行结果 echo 是打印输出字符,-e选项是开启转义功能 注意: 在windows下编写的shell脚本直 ...
- WCF 入门 (18)
前言 感冒了呀...but 不忌油炸,不忌辛辣,o(∩_∩)o . 第18集 WCF服务应该抛出fault 异常 Throwing fault exceptions from a WCF servic ...
- javascript继承(七)—用继承的方式实现照片墙功能
照片墙DEMO下载 注意:图片有四种类型:1可放大:2可拖动:3既可放大也可拖动:4都不行.由于每个图片的构造函数不同而不同(目前在火狐上调试的,其它的浏览器可能不行,请见谅,主要讲继承的思想.以后会 ...
- 第十二章:window对象
第十一章介绍了window对象及其客户端javascript所扮演的核心角色:它是客户端javascript程序的全局对象.本章介绍window对象的属性和方法,这些属性定义了不同的API,但是只有一 ...
- QQ面向对象设计
通讯项目--仿QQ聊天程序 详细设计说明书 一.引言 此项目为验证Jav ...
- 自定义EL
1.建一个类 package com.zh.util; public class GetInFo { public static String eval(String infix){ //注意的是这里 ...
- .net架构设计读书笔记--第二章 设计体系结构
第五节 探索领域架构 一.领域驱动设计的价值与意义 最初在java中使用,.net要晚些才引入.领域驱动设计出现之初的争议.一个向导,少走弯路 1. 我们真的需要DDD吗? DDD并不适用于每个软 ...
- Spring MVC设计模式
MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器 使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式.比如一批统计数据可以分别用柱状图.饼图来 ...