Disruptor多个消费者独立处理生产者消息的简单demo

disruptor如何开启多线程消费 Disruptor 是一个并发组件,可以用来快速地在多线程之间传递消息。要开启多线程消费,需要创建多个消费者,并将它们传递给 Disruptor 的构造函数。然后,Disruptor 会将消息分发到这些消费者,让它们在多个线程中并发地处理消息。 例如,下面的代码展示了如何创建并启动一个 Disruptor,并使用多个消费者处理消息: // 创建 Disruptor Disruptor<MyE... 阅读详情

第一步:创建一个实体类用于封装对象:

package Disruptor;

public class TradeTransaction {
	 private String id;//交易ID  
	    private double price;//交易金额  
	      
	    public TradeTransaction() {  
	    }  
	    public TradeTransaction(String id, double price) {  
	        super();  
	        this.id = id;  
	        this.price = price;  
	    }  
	    public String getId() {  
	        return id;  
	    }  
	    public void setId(String id) {  
	        this.id = id;  
	    }  
	    public double getPrice() {  
	        return price;  
	    }  
	    public void setPrice(double price) {  
	        this.price = price;  
	    }  
}

第二步:分别创建3个消费者的实体类:

package Disruptor;

import com.lmax.disruptor.EventHandler;

public class TradeTransactionVasConsumer implements EventHandler<TradeTransaction>{

	//消费者C1接到消息后的业务处理逻辑
	@Override
	public void onEvent(TradeTransaction arg0, long arg1, boolean arg2) throws Exception {
		// TODO Auto-generated method stub throws Exception {
		// do something....
		System.out.println("第一个消费者C1");
	}  

}


package Disruptor;

import java.util.UUID;

import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;

public class TradeTransactionInDBHandler implements EventHandler<TradeTransaction>,WorkHandler<TradeTransaction>{

	@Override
	public void onEvent(TradeTransaction event) throws Exception {
		this.onEvent(event);	
	}
	//消费者C2接到消息后的具体的业务 处理逻辑
	@Override
	public void onEvent(TradeTransaction event, long arg1, boolean arg2) throws Exception {
		 //这里做具体的消费业务逻辑,即就是接到消息后的业务处理逻辑
       // event.setId(UUID.randomUUID().toString());//随机简单生成下ID 并且打印出来 
        System.out.println("第二个消费者C2消费了消息");  
	}
}

package Disruptor;

import com.lmax.disruptor.EventHandler;

public class TradeTransactionJMSNotifyHandler implements EventHandler<TradeTransaction>{

	//消费者C3接到消息后的业务处理逻辑
	@Override
	public void onEvent(TradeTransaction arg0, long arg1, boolean arg2) throws Exception {
		//do send jms message  
		System.out.println("最后一个消费者C3");
	}

}


第 三步:创建一个生产者的实体类:


package Disruptor;

import java.util.concurrent.CountDownLatch;

import com.lmax.disruptor.dsl.Disruptor;
//创建一个发送消费事件 的类,用于发送要处理的消息
public class TradeTransactionPublisher implements Runnable {
    Disruptor<TradeTransaction> disruptor;  
    private CountDownLatch latch;
    private static int LOOP=10;//生产者发送10条消息 
    
    public TradeTransactionPublisher(CountDownLatch latch,Disruptor<TradeTransaction> disruptor) {  
        this.disruptor=disruptor;  
        this.latch=latch;  
    }  
  
	@Override
	public void run() {
		// TODO Auto-generated method stub
		TradeTransactionEventTranslator tradeTransloator=new TradeTransactionEventTranslator();  
        for(int i=0;i<LOOP;i++){  
        	System.out.println("生产者成功向Ringbuffer中发送了一条消息");
            disruptor.publishEvent(tradeTransloator);  
        }  
        latch.countDown();  
    }  
	}

第四步:编写测试类如下

package Disruptor;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.LiteBlockingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.EventHandlerGroup;
import com.lmax.disruptor.dsl.ProducerType;

public class Demo3 {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws InterruptedException {
		long beginTime = System.currentTimeMillis();
		//第一个参数用来在ring buffer中创建event,第二个参数是ring buffer的大小,第三个参数是消费者处理消息而使用的线程池。第四个参数是单或者多生产者模式,第五个参数是可选的等待策略。
		/*当消费者等待在SequenceBarrier上时,有许多可选的等待策略,不同的等待策略在延迟和CPU资源的占用上有所不同,可以视应用场景选择:

		BusySpinWaitStrategy : 自旋等待,类似Linux Kernel使用的自旋锁。低延迟但同时对CPU资源的占用也多。

		BlockingWaitStrategy : 使用锁和条件变量。CPU资源的占用少,延迟大。

		SleepingWaitStrategy : 在多次循环尝试不成功后,选择让出CPU,等待下次调度,多次调度后仍不成功,尝试前睡眠一个纳秒级别的时间再尝试。这种策略平衡了延迟和CPU资源占用,但延迟不均匀。

		YieldingWaitStrategy : 在多次循环尝试不成功后,选择让出CPU,等待下次调。平衡了延迟和CPU资源占用,但延迟也比较均匀。

		PhasedBackoffWaitStrategy : 上面多种策略的综合,CPU资源的占用少,延迟大。*/
		//以上代码主要用来设置RingBuffer.
		int bufferSize = 1024;
		ExecutorService executor = Executors.newFixedThreadPool(4);
		ThreadFactory threadFactory = Executors.defaultThreadFactory();
		// 
		@SuppressWarnings("deprecation")
/*		Disruptor<TradeTransaction> disruptor = new Disruptor<TradeTransaction>(new EventFactory<TradeTransaction>() {
			@Override
			public TradeTransaction newInstance() {
				//参数叫EventFactory,事件工场,它的职责就是产生数据填充ringBuffer区
				return new TradeTransaction();
			}
		}, bufferSize, executor, ProducerType.SINGLE, new BusySpinWaitStrategy());*/
		
		
		//我们只需要使用 Person::new 来获取Person类构造函数的引用,Java编译器会自动根据PersonFactory.create方法的签名来选择合适的构造函数。
		Disruptor<TradeTransaction> disruptor = new Disruptor<>(TradeTransaction::new, bufferSize, threadFactory,
				ProducerType.SINGLE, new LiteBlockingWaitStrategy());
		// 使用disruptor创建消费者组C1,C2
		TradeTransactionVasConsumer[] consumers = new TradeTransactionVasConsumer[2];
		for(int i =0;i<consumers.length;i++){
			consumers[i] = new TradeTransactionVasConsumer();
		}
		EventHandlerGroup<TradeTransaction> handlerGroup = disruptor.handleEventsWith(new TradeTransactionVasConsumer(),new TradeTransactionInDBHandler() );

		TradeTransactionJMSNotifyHandler jmsConsumer = new TradeTransactionJMSNotifyHandler();
		// 声明在C1,C2完事之后执行JMS消息发送操作 也就是流程走到C3
		handlerGroup.then(jmsConsumer);

		disruptor.start();// 启动
		CountDownLatch latch = new CountDownLatch(1);
		// 生产者准备
		executor.submit(new TradeTransactionPublisher(latch, disruptor));
		latch.await();// 等待生产者完事.
		disruptor.shutdown();
		executor.shutdown();

		System.out.println("总耗时:" + (System.currentTimeMillis() - beginTime));
	}

}

发送了10条数据,打印结果如下:

生产者成功向Ringbuffer中发送了一条消息
生产者成功向Ringbuffer中发送了一条消息
第一个消费者C1
生产者成功向Ringbuffer中发送了一条消息
生产者成功向Ringbuffer中发送了一条消息
生产者成功向Ringbuffer中发送了一条消息
生产者成功向Ringbuffer中发送了一条消息
生产者成功向Ringbuffer中发送了一条消息
第一个消费者C1
第一个消费者C1
第一个消费者C1
第一个消费者C1
第一个消费者C1
第一个消费者C1
第二个消费者C2消费了消息
第二个消费者C2消费了消息
生产者成功向Ringbuffer中发送了一条消息
生产者成功向Ringbuffer中发送了一条消息
生产者成功向Ringbuffer中发送了一条消息
第二个消费者C2消费了消息
第二个消费者C2消费了消息
第二个消费者C2消费了消息
第二个消费者C2消费了消息
第二个消费者C2消费了消息
第二个消费者C2消费了消息
第二个消费者C2消费了消息
第二个消费者C2消费了消息
第一个消费者C1
第一个消费者C1
第一个消费者C1
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
最后一个消费者C3
总耗时:72

有结果可以看到,生产者一共发送了10条消息,消费者C1、C2、C3分别消费了这10条消息,并且C3是在C1和C2消费完消息后才消费的生产者发的消息

SpringBoot + Disruptor后端框架,轻松实现百万级别订单并发处理 2020-04-05 14:31:19.547 INFO 7274 — [pool-1-thread-1] c.e.u.d.disrupMq.mq.HelloEventHandler : 消费者消费的信息是:MessageModel(message=消息到了,Hello world!Disruptor是LMAX在线交易平台的关键组成部分,LMAX平台使用该框架对订单处理速度能达到600万TPS,除金融领域之外,其他一般的应用中都可以用到Disruptor,它可以带来显著的性能提升。 阅读详情

相关推荐

Spring Boot 中集成 Disruptor_高性能事件处理框架

Disruptor 是一个高性能的事件处理框架,广泛应用于金融交易系统、日志记录、消息队列等领域。它通过无锁机制和环形缓冲区(Ring Buffer)实现高效的事件处理,具有极低的延迟和高吞吐量的特点。

九天的专栏 1803

springboot整合disruptor(多种消费者执行模式)

/定义用于事件处理的线程池, Disruptor通过java.util.concurrent.ExecutorSerivce提供的线程池来触发consumer的事件处理。//这么写就认定只有3个消费者 ThreadFactory executor = Executors . defaultThreadFactory();//指定事件工厂 MessageEventFactory factory = new MessageEventFactory();

qq_38639813的博客 5690

Spring Boot 使用 Disruptor 做内部消息队列

Disruptor 是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。基于 Disruptor 开发的系统单线程能支撑每秒 600 万订单,2010 年在 QCon 演讲后,获得了业界关注。Disruptor是一个开源的Java框架,它被设计用于在生产者—消费者(producer-consumer problem,简称PCP)问题上获得尽量高的吞吐量(TPS)和尽量低的延迟。

m0_71777195的博客 548

Disruptor高级(二)串行消费 & 并行消费

示例代码基础框架 Event import java.util.concurrent.atomic.AtomicInteger; /** * Disruptor中的 Event */ public class Trade { private String id; private String name; private do...

乌鲁木齐001号程序员 2281

disruptor 多个消费者

disruptor 多个消费者 但是只消费一次 有时候会有这样的需求

链家二手房信息爬取(内附完整代码)

链家二手房信息爬取1.简介2. 爬虫思路2.1 网页分析2.2 详情页分析2.3 不同页码的爬取2.4 解决链家只显示100页数据2.5 简单的反爬与进度条显示3. 总结 1.简介   最近帮同学爬取了链家在售二手房的信息,这是本人学习爬虫以来爬取数据最多的一次,就想着写个博客记录一下。   本次爬虫是利用python+jupyter notebook实现的,用到的第三方库如下: import pandas as pd # 数据存储 import requests # 网页内容获取 import re #

qq_46256922的博客 3万+

Disruptor生产和消费模式详解及高级应用(并行模式)

小伙伴们大家好,昨天的文章,带着大家扒开了Disruptor华丽的外衣,最重要的是我们知道了Disruptor高性能的原因几个重要的原因,这篇文章就在上篇文章的基础上来点实战应用。研究下Disruptor的生产和消费模式,以及高级应用,至此关于Disruptor的系列的文章,也就到此结束了,我已经尽力了,如果还有什么没能满足大家需求的,以及关于文章的内容大家有任何其他的看法的,也欢迎在评论区留言,毕竟本人才疏学浅,期待各位大佬能给小弟指点一二。

博学谷狂野架构师的博客 1946

【NVIDIA Jetson Orin系列 - 安装NVIDIA SDK Manager】

NVIDIA Jetson Orin - 安装NVIDIA SDK Manager

dally2的博客 2691

Disruptor多个消费者不重复处理生产者发送的消息的demo

上一篇介绍的一个生产者向ringbuffer发送了10条消息,每个消费者都会把这个10个消息消费一遍,但是我们还有一种需求就是要让多个消费者不重复消费消息,下面这个简单demo实现了此功能: 创建一个消息的生产者类: package Disruptor2; import com.lmax.disruptor.RingBuffer; import Disruptor.TradeTransac

java1993666的博客 5269

MATLAB实战:5步搞定GNSS单点定位解算(附完整代码)

本文提供了一份基于MATLAB的GNSS单点定位实战指南。通过5个核心步骤,详细讲解了如何从卫星坐标和伪距观测值出发,利用最小二乘迭代算法,构建并实现一个完整的单点定位解算器。文章附有完整代码,并涵盖精度评估与结果分析,适合GNSS初学者和MATLAB用户快速上手实践。

a2b3c4d5e的博客 250

CVE-2025-25249漏洞深度解析:FortiOS认证绕过与实战缓解

远程代码执行(RCE)是网络安全中最危险的漏洞类型之一,其核心往往源于认证机制失效或内存安全缺陷。CVE-2025-25249正属于此类高危漏洞——它不依赖用户凭证,也不需要交互触发,而是通过超长HTTP头(如X-Forwarded-For)引发内存越界写入,直接绕过FortiOS和FortiSwitchManager的完整认证流程。该漏洞影响广泛、CVSS评分高达9.8,凸显了嵌入式设备在HTTP协议栈实现中的深层风险。在企业网络中,FortiGate等设备常作为边界守门人,一旦失陷将导致root级控制权

weixin_33694620的博客 524

springboot项目使用Disruptor做内部消息队列

一、背景 工作中遇到项目使用Disruptor做消息队列,对你没看错,不是Kafka,也不是rabbitmq;Disruptor有个最大的优点就是快,还有一点它是开源的哦,下面做个简单的记录,如果有网友需要点个赞留个言我会补个正式项目使用的Demo哦. 二、Disruptor介绍 Disruptor 是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中......

buertianci的博客 9622

控制障碍函数(Control Barrier Function,CBF) 二、示例

使用一个经典简单的示例讲解CBF的推导

Lyajpunov的博客 6429

Disruptor实现生产者消费者

一、引入jar依赖 <!-- disruptor --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.2.1</version> </dep...

hq.zheng的博客 583

【QCA6174】QCA6174 DFS认证的时候会有概率信道不会跳转的情况,通常跳转成功概率只有25%问题分析及解决方案

Master设备需要测试的项目。

wgl307293845的博客 752

YOLO26优化:注意力魔改 | 用于微小目标检测的上下文增强和特征细化网络ContextAggregation,助力小目标检测,暴力涨点

用于微小目标检测的上下文增强和特征细化网络ContextAggregation,助力小目标检测

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 487

SpringBoot + Disruptor 实现特快高并发处理,使用Disruptor高速实现队列

SpringBoot + Disruptor 实现特快高并发处理,使用Disruptor高速实现队列

吴名氏的博客 5万+

【经验&技巧】IBIS AMI模型眼图仿真问题探讨

在ADS的仿真环境中,不论发送和接收的AMI模型是否为true或者false,都可以将通道仿真设置为统计模式,但是,如果有一方的Init函数为false,在统计模式下,处于false状态的模型将不能执行其自带的后处理功能,如下图所示,左边的统计模式和右边的逐比特模式眼图存在明显的差异,原因在于,接收端的init函数为false导致在统计模式中不能对眼图进行DFE处理,换言之,此时统计模式下的眼图就是未经任何处理的“生图”。

一只豌豆象的博客 1766

Spring Boot 使用 Disruptor 做内部高性能消息队列

Disruptor 是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。不同的地方在于,Disruptor 是在内存中以队列的方式去实现的,而且是无锁的。Disruptor是LMAX在线交易平台的关键组成部分,LMAX平台使用该框架对订单处理速度能达到600万TPS,除金融领域之外,其他一般的应用中都可以用到Disruptor,它可以带来显著的性能提升。下面介绍的概念模型,既是领域对象,也是映射到代码实现上的核心对象。

2501_92606851的博客 980

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

深入理解生产者-消费者队列

生产者-消费者关系 生产者-消费者关系个人首先在操作系统中接触到,它是信号量(Semaphore,资源使用情况的抽象)机制的一种应用。 注意:信号量在 C 语言中是一个结构体型变量,其中 int 型 value 包含表示可用资源数,value = 0:无可用资源,value < 0:有|value|个进程等待此资源。还有 L 为等待此类资源的进程 PCB 表链。一类资源对应一种信号量。 生产者-消费者关系中包含一组生产者和一组消费者,两种角色并发地操作一个共享的缓冲池。生产者向缓冲池中放入数据,消

TOCreation 2820

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

高效地传递事件——Disruptor——简单使用

disruptor.getRingBuffer() 方法通常是在你已经配置并创建了一个 Disruptor 实例后调用的,用于获取与该 Disruptor 实例关联的 RingBuffer。Disruptor 是一个高性能的环形缓冲区(Ring Buffer)库,它用于在多个生产者(Producers)和消费者(Consumers)之间高效地传递事件(Events)。RingBuffer 的大小是固定的,当达到缓冲区的末尾时,写入操作会回绕到缓冲区的开始位置。以上是文心一言生成的,自己写个小demo。

qq_45896330的博客 1074

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Spring Boot 项目使用 Disruptor 做内部消息队列

程序员的成长之路互联网/程序员/技术/资料共享关注阅读本文大概需要 6 分钟。来自:blog.youkuaiyun.com/buertianci/article/details/10532703101、背景工作中遇到项目使用Disruptor做消息队列,对你没看错,不是Kafka,也不是rabbitmq;Disruptor有个最大的优点就是快,还有一点它是开源的哦,下面做个简单的记...

良月柒 1062

SpringBoot 项目使用 Disruptor 做内部消息队列

点击关注公众号,利用碎片时间学习一、背景工作中遇到项目使用Disruptor做消息队列,对你没看错,不是Kafka,也不是rabbitmq;Disruptor有个最大的优点就是快,还有一点它是开源的哦,下面做个简单的记录.二、Disruptor介绍Disruptor 是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与...

Java笔记虾 558

Disruptor内存消息队列简单使用

Disruptor内存消息队列 最近在做一个有关使用内存消息队列到功能,比如将日志信息或点击统计信息持久化等操作,开始想着用java到内存队列作为缓冲区,后来在网上搜到Disruptor这个东西,神乎其神到,就简单了解了一下,做了一个demo,感觉还不错,可以用用,有关概念可以自行搜索,下面就简单介绍一下开发过程。 新建测试工程 新建maven工程listen-disruptor 工程目录结构如下 pom.xml文件内容 <project xmlns="http://ma.

诚的博客 1443

Disruptor入门demo

Disruptor入门demo 一、什么是 Disruptor Disruptor是一个高性能的异步处理框架,或者可以认为是最快的消息框架(轻量的JMS),也可以认为是一个观察者模式实现,或者事件-监听模式的实现,直接称disruptor模式。disruptor最大特点是高性能,其LMAX架构可以获得每秒6百万订单,用1微秒的延迟获得吞吐量为100K+。 可以理解为消费者-生产者的消息发布订阅...

Jaylon Wang的专栏 509
上一篇: HashMap、LinkedHashMap元素遍历机制探讨
下一篇: Disruptor多个消费者不重复处理生产者发送的消息的demo
java1993666
博客等级 码龄11年 22粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值