disruptor实操作手冊(二)
多消费者场景
上一篇文章介绍了怎样构建一个简单的disruptorproject之后。应该有相当一部分客官骂娘了,确实这种范例在其他地方多的是。
从这篇開始,介绍一些不一样的东西。
一,多个消费者:
之前的这一行代码是向disruptor中注入一个消费者
disruptor.handleEventsWith(new LongEventHandler() );
在实际工作中,我们并不会只使用一个消费者来运行任务,假设是这种话。也就差点儿没有什么必要来使用disruptor了。
LongEventHandler[] longEventHandlers = {new LongEventHandler(),new LongEventHandler(),new LongEventHandler()};
disruptor.handleEventsWith(longEventHandlers);
将之前那行代码替换成这两句。就可以一下注入三个消费者。
执行一下看看。三个消费者将全部的数据都处理了一遍。
2015-06-04 23:28:24,334 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理0
2015-06-04 23:28:24,334 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理0
2015-06-04 23:28:24,334 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理0
2015-06-04 23:28:24,355 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理0
2015-06-04 23:28:24,355 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理0
2015-06-04 23:28:24,356 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理0
2015-06-04 23:28:25,333 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理1
2015-06-04 23:28:25,338 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理1
2015-06-04 23:28:25,341 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理1
2015-06-04 23:28:25,353 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理1
2015-06-04 23:28:25,358 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理1
2015-06-04 23:28:25,361 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理1
2015-06-04 23:28:26,333 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理2
2015-06-04 23:28:26,333 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理2
2015-06-04 23:28:26,333 INFO [com.xuyang.test.disruptor.LongEventHandler] batch開始处理2
2015-06-04 23:28:26,354 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理2
2015-06-04 23:28:26,354 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理2
2015-06-04 23:28:26,354 INFO [com.xuyang.test.disruptor.LongEventHandler] batch结束处理2
假设你愿意,当然也能够使用一个循环语句一下子注入一万个。
看到这里大家是不是会认为更坑爹了。
谁会让一堆消费者把所有的事情都所有做一遍。
确实,我写到这里也认为非常坑爹。
那么我们再换一下看看。
二。多个不同的消费者
EventHandler[] eventHandlers = {new LongEventHandler(),new SecondEventHandler()};
disruptor.handleEventsWith(eventHandlers);
我们向disruptor中注入两个不同的消费者。
(实例中 SecondEventHandler 代码跟 LongEventHandler 全然一样。我就不贴了)
执行一下
2015-06-04 23:34:11,357 INFO [com.xuyang.test.disruptor.SecondEventHandler] 第二个消费者開始处理0
2015-06-04 23:34:11,357 INFO [com.xuyang.test.disruptor.LongEventHandler] 第一个消费者開始处理0
2015-06-04 23:34:11,378 INFO [com.xuyang.test.disruptor.LongEventHandler] 第一个消费者结束处理0
2015-06-04 23:34:11,378 INFO [com.xuyang.test.disruptor.SecondEventHandler] 第二个消费者结束处理0
2015-06-04 23:34:12,357 INFO [com.xuyang.test.disruptor.SecondEventHandler] 第二个消费者開始处理1
2015-06-04 23:34:12,357 INFO [com.xuyang.test.disruptor.LongEventHandler] 第一个消费者開始处理1
2015-06-04 23:34:12,378 INFO [com.xuyang.test.disruptor.SecondEventHandler] 第二个消费者结束处理1
2015-06-04 23:34:12,381 INFO [com.xuyang.test.disruptor.LongEventHandler] 第一个消费者结束处理1
2015-06-04 23:34:13,357 INFO [com.xuyang.test.disruptor.SecondEventHandler] 第二个消费者開始处理2
2015-06-04 23:34:13,357 INFO [com.xuyang.test.disruptor.LongEventHandler] 第一个消费者開始处理2
2015-06-04 23:34:13,378 INFO [com.xuyang.test.disruptor.LongEventHandler] 第一个消费者结束处理2
2015-06-04 23:34:13,378 INFO [com.xuyang.test.disruptor.SecondEventHandler] 第二个消费者结束处理2
这样看来,好像有一些意义了,两个不同的消费者处理全部的事件发送的数据。
在实际生产中。是会有这种场景的。比方用户须要我们砌墙,如今就能够让搬砖的和糊墙的同一时候来干活儿了。
到这里可能有的同学又有疑问了,假设我的工作就是糊墙呢,总不能让雇佣的十个糊墙工把全部的墙都糊一遍吧,要让他们一人糊一个才好。
嗯。这也是我刚開始使用disruptor这个工具所期望的事情。
三,同样功能的消费者同一时候工作
来看我这文章的你们一定都是不喜欢看源代码的家伙。或许你们也搜索了网络,可能看到了以下这种解决方式。
3.1。首先定义一个带工号的糊墙工
public class youdaoliEventHandler implements EventHandler<LongEvent> {
private static final Logger LOG = LoggerFactory
.getLogger(youdaoliEventHandler.class);
private long ordinal; //当前消费线程的编号,须要指定
private long numberOfConsumers; //总共多少个消费者
public youdaoliEventHandler(long order,long number){
ordinal = order;
numberOfConsumers = number;
}
@Override
public void onEvent(LongEvent longEvent, long sequence, boolean endOfBatch)
throws Exception {
if ((sequence % numberOfConsumers) == ordinal) {
//这是我的菜。開始业务处理
boolean chk = true;
long l = longEvent.getValue();
LOG.info("第"+ordinal+"糊墙工開始处理糊墙" + l + "");
Date dtStart = new Date();
while(chk){
Date dt = new Date();
if(dt.getTime() - dtStart.getTime() >=20){
chk = false;
LOG.info("第"+ordinal+"糊墙工開始糊墙结束" + l + "");
}
}
}
}
}
将雇来的三个糊墙工编号之后。让他们開始工作
disruptor.handleEventsWith(new youdaoliEventHandler(0,3),new youdaoliEventHandler(1,3),new youdaoliEventHandler(2,3));
执行一下看看
2015-06-04 23:58:33,537 INFO [com.xuyang.test.disruptor.youdaoliEventHandler] 第0糊墙工開始处理糊墙0
2015-06-04 23:58:33,558 INFO [com.xuyang.test.disruptor.youdaoliEventHandler] 第0糊墙工開始糊墙结束0
2015-06-04 23:58:34,535 INFO [com.xuyang.test.disruptor.youdaoliEventHandler] 第1糊墙工開始处理糊墙1
2015-06-04 23:58:34,555 INFO [com.xuyang.test.disruptor.youdaoliEventHandler] 第1糊墙工開始糊墙结束1
2015-06-04 23:58:35,539 INFO [com.xuyang.test.disruptor.youdaoliEventHandler] 第2糊墙工開始处理糊墙2
2015-06-04 23:58:35,560 INFO [com.xuyang.test.disruptor.youdaoliEventHandler] 第2糊墙工開始糊墙结束2
哇,满足了你们的期望。
一切看上去都好有道理,我居然无言以对。
我不会告诉你们,其实我在一个项目中就是这么使用的,一切执行安好。
可是,disruptor的画风不会是这么农业重金属的。
3.2,以下才是正确的画风。
首先实现一个 WorkHandle 类
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lmax.disruptor.WorkHandler; public class FirstWorkEventHandler implements WorkHandler<LongEvent> {
private static final Logger LOG = LoggerFactory
.getLogger(FirstWorkEventHandler.class);
@Override
public void onEvent(LongEvent longEvent)
throws Exception {
boolean chk = true;
long l = longEvent.getValue();
LOG.info("糊墙工開始处理" + l + "");
Date dtStart = new Date(); while(chk){
Date dt = new Date();
if(dt.getTime() - dtStart.getTime() >=20){
chk = false;
LOG.info("糊墙工结束处理" + l + "");
}
}
} }
注入三个WorkHandle消费者到disruptor中
disruptor.handleEventsWithWorkerPool(new FirstWorkEventHandler(),new FirstWorkEventHandler(),new FirstWorkEventHandler());
启动看看
2015-06-05 00:08:48,120 INFO [com.xuyang.test.disruptor.FirstWorkEventHandler] 糊墙工開始处理0
2015-06-05 00:08:48,142 INFO [com.xuyang.test.disruptor.FirstWorkEventHandler] 糊墙工结束处理0
2015-06-05 00:08:49,118 INFO [com.xuyang.test.disruptor.FirstWorkEventHandler] 糊墙工開始处理1
2015-06-05 00:08:49,138 INFO [com.xuyang.test.disruptor.FirstWorkEventHandler] 糊墙工结束处理1
2015-06-05 00:08:50,119 INFO [com.xuyang.test.disruptor.FirstWorkEventHandler] 糊墙工開始处理2
2015-06-05 00:08:50,139 INFO [com.xuyang.test.disruptor.FirstWorkEventHandler] 糊墙工结束处理2
你不须要给他们编号。三个糊墙工自觉的有条不紊的工作着。
------------------------------------------------------------
我知道你们还想了解盖一座房子要怎么安排工人,明天我会透露很多其它的信息。
disruptor实操作手冊(二)的更多相关文章
- Android实训案例(二)——Android下的CMD命令之关机重启以及重启recovery
Android实训案例(二)--Android下的CMD命令之关机重启以及重启recovery Android刚兴起的时候,着实让一些小众软件火了一把,切水果,Tom猫,吹裙子就是其中的代表,当然还有 ...
- WebLogic配置自己定义密钥库和SSL的操作手冊
WebLogic配置自己定义密钥库和SSL的操作手冊 (定制标识和定制信任&Keytool&TLS1.0) 1.启用SSLport 保存.重新启动受管Server watermark/ ...
- 实时数仓(二):DWD层-数据处理
目录 实时数仓(二):DWD层-数据处理 1.数据源 2.用户行为日志 2.1开发环境搭建 1)包结构 2)pom.xml 3)MykafkaUtil.java 4)log4j.properties ...
- Disruptor并发框架 (二)核心概念场景分析
核心术语 RingBuffer(容器): 被看作Disruptor最主要的组件,然而从3.0开始RingBuffer仅仅负责存储和更新在Disruptor中流通的数据.对一些特殊的使用场景能够被用户( ...
- zabbix3.4.7实操总结二
一,Zabbix Web操作深入 1.1 Zabbix Web下的主机和模版以及监控项的添加方式 (1)创建一个模版 我们所有的功能几乎都是在模版中定义的 我们再点进新创建的模版查看 模版里几乎可以设 ...
- Weblogic补丁升级操作手冊
1.查看Weblogic版本号 方法一 [weblogic@Weblogic201 ~]$ cd /home/weblogic/Oracle/Middleware/wlserver_10.3/serv ...
- 本地PC安裝Centos 6.5 操作手冊
http://www.xlgps.com/article/130038.html 一.准备工作 1.下载Centos6.5 ISO文件 我在官网上下的6.5版本CentOS-6.5-x86_64-bi ...
- Disruptor 高性能并发框架二次封装
Disruptor是一款java高性能无锁并发处理框架.和JDK中的BlockingQueue有相似处,但是它的处理速度非常快!!!号称“一个线程一秒钟可以处理600W个订单”(反正渣渣电脑是没体会到 ...
- MongoDB 操作手冊CRUD插入
插入操作 插入记录 1.插入一条记录 db.testData.insert({num:1,name:'a'}); 结果 WriteResult({ "nInserted" : 1 ...
随机推荐
- 计算工作日之后N天的日期
1.假期实体类: package com.smics.date; import java.io.Serializable; import java.util.Date; public class Va ...
- [POJ 1639] Picnic Planning
[题目链接] http://poj.org/problem?id=1639 [算法] 首先,我们可以用深度优先遍历求出1号节点去除后有几个联通块 设共有T个联通块,若T > K则无解,否则 : ...
- [Java] 总结1.5/1.6/1.7版本的特性
开发过程中接触到了从jdk1.5---jdk1.7的使用,在不同的阶段,都使用过了jdk的一些新特性,操作起来更加方面啦!特此总结了下,以下是测试代码: JDK1.5新特性: 1.自动装箱与拆箱: I ...
- centos6.5 + Nat网络模式 +SecureCRT 的相关设置
步骤1:先去查看子网掩码和子网ip 提示:打开后先不要关闭,后边还会使用 步骤2:查看本机名 输入: hostname 步骤3:修改本机名 vi /etc/sysconfig/network 在”Ho ...
- 【JavaScript从入门到放弃】JS基础-01
作为一个前端开发人员,JS是我们行走江湖吃饭的家伙.基本上一个前端人员能值多少大洋,就看JS了.虽然各种框架层出不穷,但是归根结底学好原生JS才是硬道理. 学习任何新东西其实都遵循 10000 小时成 ...
- readonly and const variable
共同点:都是常量: 不同点:const的值必须在编译前确定,通常在声明的同时赋值:而readonly可在运行时确定:
- React+Antd遇到的坑
第一次尝试React+antd,发现果然不愧是传说中的坑货,一个又一个坑.必须要记录. react + antd,都是最新版本,使用npm和yarn各种add,build,start 1. 资源文件, ...
- gcc和g++的区别和联系
gcc和g++都是GNU(一个组织)的编译器. 1.对于.c后缀的文件,gcc把它当做是C程序:g++当做是C++程序: 2.对于.cpp后缀的文件,gcc和g++都会当做c++程序. 3.编译阶段, ...
- BZOJ 1305: [CQOI2009]dance跳舞 网络最大流_二分答案_建模
Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会 ...
- 推荐一款能支持国密SM2浏览器——密信浏览器
密信浏览器( MeSince Browser )是基于Chromium开源项目开发的国密安全浏览器,支持国密算法和国密SSL证书,同时也支持国际算法及全球信任SSL证书:密信浏览器使用界面清新,干净. ...