当前位置: 首页 > news >正文

Disruptor 高性能环形消息框架

官方文档:Disruptor

1. 简介

        Disruptor是一个高性能的互进程(Inter-process)和多线程(Multi-threaded)消息处理库,由LMAX交易所开发,用于在Java虚拟机(JVM)上实现高性能的交换和处理数据。Disruptor的核心目标是提供一种低延迟、高吞吐量的解决方案。

一些关键特性:

  • Disruptor设计用来减少延迟,因为它避免了使用锁和线程间上下文切换,而是采用了一种基于缓存行(cache line)的设计理念。

  • 通过使用无锁编程和环形缓冲区(Ring Buffer)来实现高效的数据交换,Disruptor能够达到纳秒级别的延迟。

  • Disruptor的API简洁,易于理解和使用,使得开发者可以快速地集成到现有的系统中。

  • 它支持多种消息处理模式,包括单线程、多线程和多进程处理。

  • Disruptor基于事件驱动模型,可以处理事件的发布和订阅。

  • 它保证了事件的顺序和一致性,这对于需要顺序处理的业务场景非常重要。

  • Disruptor可以轻松地扩展以适应不同的处理需求,无论是增加消费者数量还是处理不同类型的事件。

  • 它提供了精细的内存管理策略,包括预分配内存和内存屏障(Memory Barriers)的使用,以确保数据的可见性和一致性。

Disruptor的工作流程大致如下:

  • 生产者(Producer):向环形缓冲区发布事件。

  • 消费者(Consumer):从环形缓冲区读取事件并处理。

  • 环形缓冲区(Ring Buffer):一个固定大小的缓冲区,事件被顺序地写入,并且可以被多个消费者并发读取。

  • 序列屏障(Sequence Barrier):用于同步生产者和消费者之间的进度,确保消费者不会读取到未完全写入的事件。

2. 比较

        与Spring消息监听器、Redis发布/订阅、Guava的EventBus一样,提供生产消息与消费消息的能力,极大的解耦应用程序各模块。

特性/技术DisruptorRedis发布订阅Guava EventBusSpring消息监听器
设计目的高性能、低延迟的消息处理分布式消息传递简化事件发布和订阅流程与Spring框架集成的声明式事件处理
性能极高,纳秒级延迟较高,受网络延迟影响适中,适用于中等负载适中,依赖于Spring事件传播机制
可靠性高,适合关键任务较低,消息可能会丢失适中,需要正确管理订阅和发布高,Spring框架提供事务支持
易用性低,需要深入了解并发编程高,简单的发布订阅模型高,直观的API和灵活的线程模型高,Spring框架提供注解支持
分布式支持否,仅限于单个JVM内部是,支持跨多个节点和应用的消息传递否,仅限于单个JVM内部否,仅限于单个JVM内部(除非结合消息中间件)
线程模型无锁设计,多线程多线程,基于发布订阅机制支持同步和异步事件分发支持同步和异步事件分发
适用场景高性能计算,如金融交易系统分布式系统的消息传递,如微服务架构简单的事件驱动应用,需要灵活的事件处理需要Spring框架支持的企业级应用
配置复杂度高,需要配置事件、工厂和处理器低,Redis简单配置即可使用低,通过注解或API简单配置低,Spring框架自动配置
社区和文档活跃,由LMAX提供支持非常活跃,Redis社区广泛支持活跃,Guava库由Google维护非常活跃,Spring社区广泛支持
扩展性高,可以自定义事件和处理器高,可以与其他Redis特性结合使用高,可以自定义事件处理逻辑高,可以自定义事件和监听器
持久性否,内存中处理,不提供持久化是,可以结合Redis持久化选项否,内存中处理,不提供持久化可以结合数据库事务管理持久化

3. 实例

3.1 添加依赖

<!--        disruptor-->
<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version>
</dependency>

3.2 消息实体

package org.example.event;public class TradeEvent {private long tradeId;private String symbol;private double price;private int volume;// Constructor, getters and setterspublic TradeEvent() {}public long getTradeId() {return tradeId;}public void setTradeId(long tradeId) {this.tradeId = tradeId;}public String getSymbol() {return symbol;}public void setSymbol(String symbol) {this.symbol = symbol;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public int getVolume() {return volume;}public void setVolume(int volume) {this.volume = volume;}
}

3.3 消息实体工厂

import com.lmax.disruptor.EventFactory;public class TradeEventFactory implements EventFactory<TradeEvent> {@Overridepublic TradeEvent newInstance() {return new TradeEvent();}
}

3.4 消息处理器

public class TradeEventHandler implements EventHandler<TradeEvent> {@Overridepublic void onEvent(TradeEvent event, long sequence, boolean endOfBatch) {System.out.println(String.format("Trade Event. ID: %d, Symbol: %s, Price: %.2f, Volume: %d",event.getTradeId(), event.getSymbol(), event.getPrice(), event.getVolume()));}
}

3.5 配置disruptor启动器

package org.example.config;import com.lmax.disruptor.dsl.Disruptor;
import org.example.event.TradeEvent;
import org.example.event.TradeEventFactory;
import org.example.event.TradeEventHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.Executor;
import java.util.concurrent.Executors;@Configuration
public class DisruptorConfig {@Beanpublic Disruptor<TradeEvent> disruptor() {int bufferSize = 1024;Executor executor = Executors.newCachedThreadPool();Disruptor<TradeEvent> disruptor = new Disruptor<>(new TradeEventFactory(), bufferSize, executor);disruptor.handleEventsWith(new TradeEventHandler());System.out.println("Disruptor created.");disruptor.start();return disruptor;}}

3.6 测试

curl --request POST \--url 'http://localhost:8080/trade?apipost_id=35ef4f1dbd9000' \--header 'Accept: */*' \--header 'Accept-Encoding: gzip, deflate, br' \--header 'Connection: keep-alive' \--header 'Content-Type: application/json' \--header 'User-Agent: PostmanRuntime-ApipostRuntime/1.1.0' \--data '{"tradeId":1111,"symbol":"测试标记","price":32.3,"volume":3
}'

控制台输出

Trade Event. ID: 1111, Symbol: 测试标记, Price: 32.30, Volume: 3

相关文章:

Disruptor 高性能环形消息框架

官方文档&#xff1a;Disruptor 1. 简介 Disruptor是一个高性能的互进程&#xff08;Inter-process&#xff09;和多线程&#xff08;Multi-threaded&#xff09;消息处理库&#xff0c;由LMAX交易所开发&#xff0c;用于在Java虚拟机&#xff08;JVM&#xff09;上实现高性能…...

Python列表(二)

方式三&#xff1a; 创建对应的枚举对象 概念&#xff1a;通过枚举函数&#xff0c;生成一个新的对象 作用&#xff1a;函数用于将一个可遍历的数据对象&#xff08;如列表、元组或字符串&#xff09;组合为一个索引序列 同时列出数据下标和数据 #生成枚举对象 values [&…...

计算机网络:应用层 —— 网络应用模式

文章目录 客户—服务器方式和对等方式客户/服务器方式 (C/S方式)工作流程特点 对等方式 (P2P方式)工作流程P2P 应用特点 客户—服务器方式和对等方式 网络应用程序运行在处于网络边缘的不同的端系统上&#xff0c;通过彼此间的通信来共同完成某项任务。 开发一种新的网络应用…...

@Repository注解和@mapper的区别

1. Repository 注解 通俗解释&#xff1a; 你可以把 Repository 注解想象成是一个专门负责管理数据库操作的 “仓库管理员”。这个管理员主要负责和数据库打交道&#xff0c;就像管理一个大仓库一样&#xff0c;他会进行各种操作&#xff0c;比如把货物&#xff08;数据&#x…...

解锁成长密码:探寻刻意练习之道

刻意练习&#xff0c;真有那么神&#xff1f; 在生活中&#xff0c;你是否有过这样的困惑&#xff1a;每天苦练英语口语&#xff0c;可一到交流时还是支支吾吾&#xff1b;埋头苦学吉他&#xff0c;却总是卡在几个和弦转换上&#xff1b;工作多年&#xff0c;业务能力却似乎陷入…...

cuda-cuDnn

cuda sudo /bin/sh cuda_11.7.0_515.43.04_linux.run cudnn cuDNN Archive | NVIDIA Developer Linux 系统 CUDA 多版本共存以及切换 – 颢天 安装cuda # 如果已经安装过驱动&#xff0c;驱动不需要再安装&#xff0c;取消勾选 安装cuDNN&#xff0c;cuda-cuDNN对应关系见…...

如何使用Python和PIL库生成带竖排文字的封面图像

在今天的博客中&#xff0c;我们将学习如何使用Python和PIL&#xff08;Pillow&#xff09;库生成一个简单而有创意的封面图像。我们将创建一个背景图像&#xff0c;并在其上绘制带有竖排文字的标题和副标题&#xff0c;最后再添加一些装饰性元素如星星和萤火虫。这个教程适合初…...

低代码开发 实战转型案例一览

数字浪潮澎湃&#xff0c;企业应用开发需求呈井喷之势。传统全栈开发虽底蕴深厚&#xff0c;然其漫长周期与高昂成本&#xff0c;难以追赶市场快速交付的急切步伐。无代码与低代码平台顺势崛起&#xff0c;宛如暗夜明灯&#xff0c;吸引非技术人员纷至沓来&#xff0c;投身应用…...

SQL Server中FIRST_VALUE和 LAST_VALUE窗口函数允许在一个指定的窗口内返回第一个或最后一个值

在 SQL Server 中&#xff0c;FIRST_VALUE 和 LAST_VALUE 是用于窗口函数&#xff08;Window Functions&#xff09;的两个非常有用的函数。它们允许你在一个指定的窗口内返回第一个或最后一个值。这两个函数通常与 OVER 子句一起使用&#xff0c;以定义窗口的范围和排序规则。…...

机器学习-高斯混合模型

文章目录 高斯混合模型对无标签的数据集&#xff1a;使用高斯混合模型进行聚类对有标签的数据集&#xff1a;使用高斯混合模型进行分类总结 高斯混合模型 对无标签的数据集&#xff1a;使用高斯混合模型进行聚类 对有标签的数据集&#xff1a;使用高斯混合模型进行分类 总结...

微信V3支付报错 平台证书及平台证书序列号

1.平台证书及平台证书序列号设置错误报错&#xff1a; 错误1&#xff1a; Verify the response’s data with: timestamp1735184656, noncea5806b8cabc923299f8db1a174f3a4d0, signatureFZ5FgD/jtt4J99GKssKWKA/0buBSOAbWcu6H52l2UqqaJKvrsNxvodB569ZFz5G3fbassOQcSh5BFq6hvE…...

41.欠采样技术下变频不能用与跨两个nyquist的情况下

当接收到的信号位于同一nyquist区间时&#xff0c;信号被成功的折叠到了第一Nyquist区间中。 当接收信号位于两个或多个采样区间时&#xff0c;最后多个区间的信号都会被折叠到第一Nyquist区间中造成信号的重叠。...

20241227通过配置nomodeset参数解决更新grub之后,ubuntu20.04.5无法启动的问题

20241227通过配置nomodeset参数解决更新grub之后&#xff0c;ubuntu20.04.5无法启动的问题 2024/12/27 17:34 0.397475]pci0000:00:07.0:DPC:RPPI0 l0gsize 0 is invalid dev/nvmeon1p9:clean,251849/4276224 files,3266309/17089792 blocks 缘起&#xff1a;公司电脑要安装加密…...

从 GitLab.com 到 JihuLab.com 的迁移指南

本文分享从 GitLab.com 到 JihuLab.com 的迁移指南。 近期&#xff0c;GitLab Inc. 针对其 SaaS 产品做了限制&#xff0c;如果被判定为国内用户&#xff0c;则会建议使用其在国内的发布版本极狐GitLab。从 GitLab SaaS 产品&#xff08;GitLab.com&#xff09;迁移到极狐GitL…...

深度学习中的并行策略概述:2 Data Parallelism

深度学习中的并行策略概述&#xff1a;2 Data Parallelism 数据并行&#xff08;Data Parallelism&#xff09;的核心在于将模型的数据处理过程并行化。具体来说&#xff0c;面对大规模数据批次时&#xff0c;将其拆分为较小的子批次&#xff0c;并在多个计算设备上同时进行处…...

Python大数据可视化:基于Python对B站热门视频的数据分析与研究_flask+hive+spider

开发语言&#xff1a;Python框架&#xff1a;flaskPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 排行榜界面 系统管理界面 看板展示 摘要 本项目以对B站热…...

利用 Python 编写一个 VIP 音乐下载脚本

在这篇博客中,我们将介绍如何使用 Python 编写一个简单的 VIP 音乐下载脚本,利用网页爬虫技术从一个音乐网站下载歌曲。通过解析网页,获取歌曲的真实下载链接,并将音乐文件保存到本地。我们将使用 requests 和 BeautifulSoup 库来实现这个过程。 目标 本脚本的主要功能是…...

linux内核如何实现TCP的?

TCP(传输控制协议)是网络通信中的核心协议之一,实现了可靠的、面向连接的、基于字节流的通信。在Linux内核中,TCP的实现相对复杂,涉及多个模块和层次。以下是一些关键概念和机制: 1. 协议栈 Linux 内核中的网络协议栈(Network Stack)是分层设计的,包括链路层、网络层…...

【Spring】基于XML的Spring容器配置——FactoryBean的使用

随着Spring框架应用程序的复杂性增加&#xff0c;开发者需要更加灵活和强大的工具来创建和管理Bean。FactoryBean是Spring提供的一种强大机制&#xff0c;它允许开发者自定义Bean的创建过程。这种机制不仅提高了Bean的创建灵活性&#xff0c;还可以简化复杂对象的构建过程。 在…...

Docker使用——国内Docker的安装办法

文章目录 参考资料前言Mac安装办法Homebrew 安装1. 直接下报错2. 安装homebrew&#xff0c; 用国内镜像3. 安装Docker4. 启动docker服务5. 测试是否安装成功 参考资料 鸣谢大佬文章。 macOS系统中&#xff1a;Docker的安装&#xff1a;https://blog.csdn.net/sulia1234567890…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...