ZeroMQ(java)之Router/Dealer模式
本教程转自:http://blog.csdn.net/kobejayandy/article/details/20163527
在开始之前先把guid里面提到的几个ZeroMQ的特性列一下吧:
(1)ZeroMQ有自己的I/O线程来异步的处理I/O,而且后台采用了无锁的数据结构
(2)在ZeroMQ中,所有的组件都可以动态的加入和移除,而且可以启动组件以任何的顺利,例如我们可以先启动request,再启动response,依然可以工作,而且还会自动的重连接。
(3)如果有需要的话,会自动的将message进行排队,当然这都是有一套的模式的,一般情况下会尽量早的将数据发送到receiver。
(4)当缓冲的message队列满了以后,ZeroMQ有自己的行为,有的组件会阻塞,有的则会将message抛弃。
(5)底层的通信可以采用各种各样的都行,例如TCP,IPC啥的。
(6)它会自动的处理那些比较慢而且阻塞的reader
(7)支持message的路由
(8)ZeroMQ确保全部的数据被receiver接收到,例如发送10K,那么也接受到10K
(9)它发送的数据格式是二进制,所以对发送的内容无要求
(10)ZeroMQ会自动处理网络错误,而且会自动尝试恢复
(11)节能。。。(我擦,居然还有这个)
好了,先来看一下poller这个东西吧,蛮有意思的,类似与epoll或者java里面的selector,
在前面的例子中我们都只是创建一个socket,那如果我们要创建两个socket在同一个线程中该怎么处理呢,那么这个时候就可以用到poller这东西了。。。可以将已经建立好的socket注册到poller上面去,并注册相应的事件。。
这里就用push/pull来举例子吧,就直接来看pull端的代码吧:
- package poller;
- import org.zeromq.ZMQ;
- public class Pull {
- public static void main(String args[]) {
- ZMQ.Context context = ZMQ.context();
- ZMQ.Socket pull1 = context.socket(ZMQ.PULL); //创建一个pull
- pull1.connect("tcp://127.0.0.1:5555"); //建立于push的连接
- ZMQ.Socket pull2 = context.socket(ZMQ.PULL);
- pull2.connect("tcp://127.0.0.1:5555");
- ZMQ.Poller poller = new ZMQ.Poller(); //创建一个大小为2的poller
- poller.register(pull1, ZMQ.Poller.POLLIN); //分别将上述的pull注册到poller上,注册的事件是读
- poller.register(pull2, ZMQ.Poller.POLLIN);
- int i = ;
- while (!Thread.currentThread().isInterrupted()) {
- poller.poll();
- if (poller.pollin()) {
- while (null != pull1.recv(ZMQ.NOBLOCK)) { //这里采用了非阻塞,确保一次性将队列中的数据读取完
- i++;
- }
- }
- if (poller.pollin()) {
- while (null != pull2.recv(ZMQ.NOBLOCK)) {
- i++;
- }
- }
- if (i % == ) {
- System.out.println(i);
- }
- }
- pull1.close();
- pull2.close();
- context.term();
- }
- }
这里还算简单吧,同时创建了两个pull,都将他们注册到了poller上面去。。。其实这个样子很像是selector或者epoll啥的。。。
好啦,接下来进入正题:
request/response算是一种非常常用的模式了,但是前面的例子中,我们的response端都只能在单线程中运行,因为必须要recv与send配对使用,那么就很大程度上限制了response的伸缩性,如果有大量的request来提交很多request请求的话,那么性能将会受到极大的限制,当然这种情况下我们可以采用如下的方式来解决:
这里让request同时连接到多个response,这里就可以将request请求分散到多个response,这样当有多个request的时候的性能要求。。。但是有一个问题,如果我们又10个request端,他们每一个都不断的提交request请求,这个时候我们的reponse可能就会很忙,那么在这种结构下无法动态的添加response,依然限制了整个系统的伸缩性。。。
那么最终的解决方案就来了:
这里可以看到,在request端与response端之间加了一个中间层,可以将其看成一个路由器,它将request端的请求路由到response端,如果性能不够的话,可以再建立新的response将其连接到中间层就可以了,就方便的解决系统的伸缩性问题了。。。
好了,这里直接就上中间层与response端的代码吧:
- package multireqrep;
- import org.zeromq.ZMQ;
- public class Response {
- public static void main(String args[]) {
- final ZMQ.Context context = ZMQ.context();
- ZMQ.Socket router = context.socket(ZMQ.ROUTER);
- ZMQ.Socket dealer = context.socket(ZMQ.DEALER);
- router.bind("ipc://fjs1");
- dealer.bind("ipc://fjs2");
- for (int i = ; i < ; i++) {
- new Thread(new Runnable(){
- public void run() {
- // TODO Auto-generated method stub
- ZMQ.Socket response = context.socket(ZMQ.REP);
- response.connect("ipc://fjs2");
- while (!Thread.currentThread().isInterrupted()) {
- response.recv();
- response.send("hello".getBytes());
- try {
- Thread.currentThread().sleep();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- response.close();
- }
- }).start();
- }
- ZMQ.proxy(router, dealer, null);
- router.close();
- dealer.close();
- context.term();
- }
- }
好吧,代码还算蛮简单的,直接用了ZeroMQ定义的router和dealer组件,以及内置的proxy方法就好了。。。
嗯,再来赞叹一次,ZeroMQ确实好用。。。
ZeroMQ(java)之Router/Dealer模式的更多相关文章
- ZeroMQ(java)之Router与Dealer运行原理
在开始这部分的内容之前,先来看看ZeroMQ中HWM概念---High-Water Marks 当系统的数据量很大,而且发送频率很高的情况下,内存就很重要了,如果处理不好会出现很多问题,例如如下场景: ...
- ZeroMQ(java)中的数据流SessionBase与SocketBase
前面的文章中已经比较的清楚了ZeroMQ(java)中如何在底层处理IO, 通过StreamEngine对象来维护SelectableChannel对象以及IO的事件回调,然后通过Poller对象来维 ...
- ZeroMQ(JAVA)中的数据流,SessionBase与SocketBase
前面的文章中已经比较的清楚了ZeroMQ(java)中如何在底层处理IO, 通过StreamEngine对象来维护SelectableChannel对象以及IO的事件回调,然后通过Poller对象来维 ...
- java运行时内存模式学习
学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoa ...
- java设计模式之原型模式
原型模式概念 该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.java中复制通过clone()实现的.clone中涉及深.浅复制.深.浅复制的概念如下: ⑴浅复制 ...
- Java设计模式——装饰者模式
JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...
- ZeroMQ(java)中监控Socket
基本上ZeroMQ(java)中基本的代码都算是过了一遍了吧,不过觉得它在日志这一块貌似基本没有做什么工作,也就是我们通过日志来知道ZeroMQ都发生了什么事情.. 而且由于ZeroMQ中将连接的建立 ...
- 说说Java中的代理模式
今天看到传智播客李勇老师的JDBC系列的第36节——通过代理模式来保持用户关闭连接的习惯.讲的我彻底蒙蔽了,由于第一次接触代理模式,感到理解很难,在博客园找到一篇文章,先记录如下: 引用自java设计 ...
- java反射机制(工厂模式)
http://www.phpddt.com/dhtml/338.html java里面没有typeof,js有. 我终于实现了用反射机制编写的工厂模式.java反射在工厂模式可以体现. 包含产品接口类 ...
随机推荐
- Scala 中的函数式编程基础(三)
主要来自 Scala 语言发明人 Martin Odersky 教授的 Coursera 课程 <Functional Programming Principles in Scala>. ...
- Boostrap响应式与非响应式
非响应式布局 在使用非响应式布局时,在<head>标签中需要加入一下内容,其中最主要的是non-responsive.css文件 <head> <meta http-eq ...
- JSON Web Token - 在Web应用间安全地传递信息(zhuan)
来自 http://blog.leapoahead.com/2015/09/06/understanding-jwt/ JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允许我们使用 ...
- go语言的模板,text/template包
go语言的模板,text/template包 定义 模板就是将一组文本嵌入另一组文本里 传入string--最简单的替换 package main import ( "os" &q ...
- 团队项目--关于QQ项目的运行和总结
目前为止该QQ项目实现如下功能:添加好友到好友列表,可以把好友在不同分类中移动,同时支持离线查找添加好友,离线更换头像,离线发送消息,保存所有好友聊天记录,发送窗口抖动,查看对方信息,更改/添加信息等 ...
- json2form已改名为AForm
相信大部分程序员都接触过表单,表单是收集用户输入的不二之选,但是表单的开发又是最繁琐.最复杂的,简单地说,开发表单你需要涉及到很多知识: 布局,表单如何布局排版,看起来最清晰整洁,且符合用户体验 控件 ...
- 7.Android之评分条RatingBar和拖动条SeekBar学习
评分条RatingBar和拖动条SeekBar很常见,今天来学习下. (1)RatingBar评分条 如图: <RelativeLayout xmlns:android="http:/ ...
- NOI题库-小学奥赛QwQ
今天Loli教育我们让我们来看看NOI题库的奥赛部分,不过,为何是小学的( ⊙ o ⊙ )啊!感觉智商被各种侮辱. 余数相同问题: 描述 已知三个正整数 a,b,c. 现有一个大于1的整数x,将其作为 ...
- Process manufacturing和Discrete manufacturing的区别
Process manufacturing(Process industry) 加工制造,或者加工工业.其一个重要特征是,原材料被加工成成品后,我们再也无法将它恢复成原料,比如,苹果罐头,我们再没法把 ...
- 深入解析MySQL分区(Partition)功能
自5.1开始对分区(Partition)有支持 = 水平分区(根据列属性按行分)= 举个简单例子:一个包含十年发票记录的表可以被分区为十个不同的分区,每个分区包含的是其中一年的记录. === 水平分区 ...
