支撑每秒数百万订单无压力,SpringBoot + Disruptor 太猛了!

news2024/10/21 11:03:56

文章目录

  • 一、支撑每秒数百万订单无压力,SpringBoot + Disruptor 太猛了!
  • 二、项目环境配置
    • 1.Maven 配置 (pom.xml)
    • 2.Yaml 配置 (application.yml)
    • 3.Disruptor 的核心实现
    • 4.定义事件工厂(OrderEventFactory)
    • 5.定义事件处理器(OrderEventHandler)
    • 6.定义生产者(OrderEventProducer)
    • 7.配置 Disruptor
    • 8.生产订单事件
    • 9.前端页面展示
  • 三,运行流程说明
  • 总结


一、支撑每秒数百万订单无压力,SpringBoot + Disruptor 太猛了!

在高并发系统中,传统的队列或锁机制往往无法满足极限情况下的性能需求。Disruptor 是由 LMAX 交易所开发的一种高性能并发框架,设计初衷就是为了解决高频金融交易中的并发处理问题。与传统的队列机制不同,Disruptor 采用环形缓冲区(RingBuffer)和无锁算法(Lock-Free Algorithm),最大程度地减少了线程上下文切换和内存屏障的开销,从而能够在高并发场景下提供极低的延迟和极高的吞吐量。

Disruptor 的核心特性包括:

  1. 无锁设计:通过使用无锁算法,Disruptor 避免了传统锁机制的竞争问题,从而大幅提升了系统的吞吐量。
  2. 低延迟:Disruptor 可以在纳秒级别处理事件,确保系统在高并发场景下的极低延迟。
  3. 高吞吐量:由于无锁设计和高效的缓存使用,Disruptor 能够轻松处理每秒数百万级别的事件。
  4. 环形缓冲区:通过环形缓冲区,Disruptor 能够高效利用内存,并且避免了垃圾回收机制带来的性能损耗。

下面是 LMAX 如何在其高性能核心服务(例如交易所)中使用 Disruptor 的一个例子。
在这里插入图片描述

本文将详细讲解如何通过 Spring Boot 集成 Disruptor,实现每秒百万订单的无压力处理,并提供完整的代码示例,助你轻松应对高并发挑战。

二、项目环境配置

1.Maven 配置 (pom.xml)

首先,我们需要在 pom.xml 中引入必要的依赖项,包括 Spring BootDisruptor

<dependencies>
    <!-- Spring Boot 相关依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    <!-- Disruptor 依赖 -->
    <dependency>
      <groupId>com.lmax</groupId>
      <artifactId>disruptor</artifactId>
      <version>4.0.0</version>
  </dependency>

    <!-- 其他依赖 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

2.Yaml 配置 (application.yml)

application.yml 中,我们可以进行一些常规的 Spring Boot 配置,例如端口号设置等:

代码如下(示例):

server:
  port: 8080

spring:
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html

3.Disruptor 的核心实现

定义订单事件(OrderEvent)
首先,我们定义一个简单的订单事件类 OrderEvent,它将存储订单的基本信息:

package com.icoderoad.disruptor.entity;

import lombok.Data;

@Data
public class OrderEvent {
    private String orderId;
    private String userId;
    private double price;
    private String status;
}

4.定义事件工厂(OrderEventFactory)

事件工厂用于生成 OrderEvent 对象:

package com.icoderoad.disruptor.factory;

import com.lmax.disruptor.EventFactory;
import com.icoderoad.disruptor.entity.OrderEvent

public class OrderEventFactory implements EventFactory<OrderEvent> {
    @Override
    public OrderEvent newInstance() {
        return new OrderEvent();
    }
}

5.定义事件处理器(OrderEventHandler)

事件处理器是实际处理事件的地方。在这里,我们模拟订单处理的逻辑:

package com.icoderoad.disruptor.handler;

import com.icoderoad.disruptor.entity.OrderEvent
import com.lmax.disruptor.EventHandler;

public class OrderEventHandler implements EventHandler<OrderEvent> {

    @Override
    public void onEvent(OrderEvent event, long sequence, boolean endOfBatch) {
        // 处理订单的具体业务逻辑
        processOrder(event);
    }

    private void processOrder(OrderEvent orderEvent) {
        // 模拟订单支付逻辑
        System.out.println("处理订单: " + orderEvent.getOrderId() + ", 用户: " + orderEvent.getUserId() + ", 金额: " + orderEvent.getPrice());

        // 假设订单处理通过后更新订单状态
        orderEvent.setStatus("已支付");

        // 模拟库存扣减逻辑
        reduceInventory(orderEvent);

        System.out.println("订单处理完成: " + orderEvent.getOrderId() + " 状态: " + orderEvent.getStatus());
    }

    private void reduceInventory(OrderEvent orderEvent) {
        // 模拟库存扣减逻辑
        System.out.println("扣减库存: 订单 " + orderEvent.getOrderId());
        // 假设库存扣减成功
    }
}

6.定义生产者(OrderEventProducer)

生产者负责将订单事件发布到 DisruptorRingBuffer 中:

package com.icoderoad.disruptor.producer;


import com.icoderoad.disruptor.entity.OrderEvent
import com.lmax.disruptor.RingBuffer;

import java.util.UUID;

public class OrderEventProducer {
    private final RingBuffer<OrderEvent> ringBuffer;

    public OrderEventProducer(RingBuffer<OrderEvent> ringBuffer) {
        this.ringBuffer = ringBuffer;
    }

    public void onData(String userId, double price) {
        long sequence = ringBuffer.next();  // 获取下一个序列号
        try {
            OrderEvent orderEvent = ringBuffer.get(sequence); // 获取事件对象
            orderEvent.setOrderId(UUID.randomUUID().toString());
            orderEvent.setUserId(userId);
            orderEvent.setPrice(price);
            orderEvent.setStatus("未支付");
        } finally {
            ringBuffer.publish(sequence);  // 发布事件
        }
    }
}

7.配置 Disruptor

Spring Boot 中配置 Disruptor 并启动它:

package com.icoderoad.disruptor.config;

import com.lmax.disruptor.dsl.Disruptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.icoderoad.disruptor.entity.OrderEvent
  import com.icoderoad.disruptor.factory.OrderEventFactory

import java.util.concurrent.Executors;

@Configuration
public class DisruptorConfig {

    @Bean
    public Disruptor<OrderEvent> disruptor() {
        OrderEventFactory factory = new OrderEventFactory();
        int bufferSize = 1024; // RingBuffer 大小

        Disruptor<OrderEvent> disruptor = new Disruptor<>(factory, bufferSize, Executors.defaultThreadFactory());

        // 绑定事件处理器
        disruptor.handleEventsWith(new OrderEventHandler());
        disruptor.start();
        return disruptor;
    }

    @Bean
    public OrderEventProducer orderEventProducer(Disruptor<OrderEvent> disruptor) {
        return new OrderEventProducer(disruptor.getRingBuffer());
    }
}

8.生产订单事件

通过 REST API 接收订单请求,并将订单事件发布到 Disruptor

package com.icoderoad.disruptor.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import com.icoderoad.disruptor.producer.OrderEventProducer;

@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private OrderEventProducer orderEventProducer;

    @PostMapping("/create")
    public ResponseEntity<String> createOrder(@RequestBody OrderRequest orderRequest) {
        orderEventProducer.onData(orderRequest.getUserId(), orderRequest.getPrice());
        return ResponseEntity.ok("订单创建成功,正在处理!");
    }
}

class OrderRequest {
    private String userId;
    private double price;

    // Getters and Setters

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

9.前端页面展示

为了更直观地展示订单的创建,我们使用 Thymeleaf 模板引擎,配合 Bootstrap 构建一个简单的订单创建页面。

Thymeleaf 模板 (order.html)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>创建订单</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <h1>创建订单</h1>
    <form id="orderForm">
        <div class="mb-3">
            <label for="price" class="form-label">价格</label>
            <input type="number" class="form-control" id="price" name="price" required>
        </div>
        <button type="submit" class="btn btn-primary">提交</button>
    </form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
    document.getElementById('orderForm').addEventListener('submit', function (e) {
        e.preventDefault();
        const price = document.getElementById('price').value;
        fetch('/orders/create', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({price: price}),
        })
        .then(response => response.text())
        .then(data => alert(data))
        .catch(error => console.error('Error:', error));
    });
</script>
</body>
</html>

三,运行流程说明

  1. 当用户通过前端页面提交订单请求时,OrderController 接收到请求并调用 OrderEventProducer 发布订单事件。
  2. 订单事件发布到 DisruptorRingBuffer 中,并自动触发 OrderEventHandler 的消费逻辑。
  3. OrderEventHandler 处理订单的业务逻辑,包括支付处理、库存扣减等操作,并更新订单状态。
  4. 订单处理完成后,控制台输出相关处理信息。

总结

本文通过一个具体的订单处理场景,展示了如何结合 Spring Boot 与 Disruptor 实现高性能的并发处理。通过无锁的设计和高效的事件处理机制,Disruptor 能够轻松应对每秒数百万订单的处理需求。在高并发场景下,Disruptor 是一种非常值得考虑的解决方案。

今天就讲到这里,如果有问题需要咨询,大家可以直接留言找我,我们会尽力为你解答。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2213744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

概率 随机变量以及分布

一、基础定义及分类 1、随机变量 随机变量是一个从样本空间&#xff08;所有可能结果的集合&#xff09;到实数集的函数。&#xff08;随机变量的值可以是离散的&#xff0c;也可以是连续的。 &#xff09; 事件可以定义为随机变量取特定值的集合。 2、离散型随机变量 随机变…

怎么才能算AI智能体?

科技界对 AI 智能体的痴迷愈演愈烈。销售从智能体到自动化系统&#xff0c;比如像 Salesforce 和 Hubspot 这样的公司声称可以提供具有颠覆性的 AI 智能体。但是&#xff0c;我还没有看到一个真正令人信服、完全自主的基于 LLM 的智能体。市场上充斥着各种 “废物机器人”&…

OIDS与ERP:物料管理的高效协同

添加HanTop-MKT&#xff0c;咨询物料管理协同解决方案 客户案例 背景&#xff1a; 在当前快速发展的3C自动化行业&#xff0c;企业面临着前所未有的挑战。产品生命周期的缩短、个性化需求的增长以及市场变化的加速&#xff0c;都要求企业必须具备快速响应的能力。在这样的环…

一个月学会Java 第15天 枚举与Debug

Day15 枚举与Debug 这节课我们来看看枚举&#xff0c;和Debug&#xff0c;当我们学完并会用debug之后呢&#xff0c;编码会非常的舒服&#xff0c;而且debug就是调试嘛&#xff0c;所以我们会了debug之后&#xff0c;在程序哪里出问题也可以进行锁定。 第一章 枚举 枚举并不是非…

Spring Boot知识管理:提升团队协作效率

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

探索巅峰性能 |迅为 RK3588开发板深度剖析

RK3588作为瑞芯微公司旗下一款高端处理器的杰出代表&#xff0c;凭借卓越的性能与多样化的外设接口成为了众多开发和爱好者的首选。随着RK3588在市场上的广泛应用&#xff0c;大家不禁要提出疑问&#xff1a;RK3588究竟强在何处&#xff1f;在2022年&#xff0c;北京迅为电子推…

【Linux网络编程】--- Linux基本指令(上)

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Linux网络编程 &#x1f3e0; ls命令 语法 : ls -[选项] [目录或文件] 功能 : 对于目录,该命令列出该目录下的所有子目录与文件;对于文件,将列出文件名…

STL.string(上)

string string类string类构造string类对象的容量操作size和lengthmax_sizeappend小总结下size、capacity、append、operatorresizereserve 初识迭代器附录1. vs下string结构的说明&#xff08;解释前文为什么capacity是16而不是别的&#xff09; 由于string创始初期没有参照导致…

1.centos 镜像

centos 它有官网的下载地址&#xff1a;https://vault.centos.org/ 选择想要的版本&#xff0c;我选择 centos7.8 进入到镜像目录 isos 选择 x86_64 选择想要的版本&#xff0c;我选择 CentOS-7-x86_64-DVD-2003.iso 安装就正常安装就行。我选择虚拟机安装。这个参考&…

一区鱼鹰优化算法+深度学习+注意力机制!OOA-TCN-LSTM-Attention多变量时间序列预测

一区鱼鹰优化算法深度学习注意力机制&#xff01;OOA-TCN-LSTM-Attention多变量时间序列预测 目录 一区鱼鹰优化算法深度学习注意力机制&#xff01;OOA-TCN-LSTM-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.基于OOA-TCN-LSTM-Attenti…

Java 入门基础篇11 - java基础语法

一 流程控制 1.1 流程控制语句介绍 一个java程序有很多条语句组成&#xff0c;流程控制语句是用来控制程序中的各语句执行的顺序&#xff0c;通过流程语句控制让程序执行顺序达到我们想要实现的功能。 其流程控制方式采用结构化程序设计中规定的三种基本流程结构&#xff1a;…

金融信用评分卡建模项目:AI辅助

最近我一直忙着开发一个信用评分卡建模工具&#xff0c;所以没有时间更新示例或动态。今天&#xff0c;我很高兴地跟大家分享&#xff0c;这个工具的基本框架已经完成了&#xff0c;并且探索性的将大语言模型&#xff08;AI&#xff09;整合了进去。目前ai在工具中扮演智能助手…

探索人工智能:深度解析未来科技的核心驱动力

目录 &#x1f354; 人工智能的应用方向 &#x1f354; 人工智能的发展历史 &#x1f354; 人工智能、机器学习、深度学习关系 &#x1f354; 为什么学习机器学习&#xff1f; &#x1f354; 小节 学习目标 &#x1f340; 了解人工智能的应用方向 &#x1f340; 了解人工智…

CICD持续集成交付与持续交付

一 CICD是什么 CI/CD 是指持续集成&#xff08;Continuous Integration&#xff09;和持续部署&#xff08;Continuous Deployment&#xff09;或持续交付&#xff08;Continuous Delivery&#xff09; 1.1 持续集成&#xff08;Continuous Integration&#xff09; 持续集成…

javascript object

用const去define一个constant 用let (如果要reassign的话) 一个变量。

每天3分钟,彻底弄懂神经网络的优化器(十一)AdamW

1. AdamW算法的提出 AdamW算法是由Ilya Loshchilov和Frank Hutter提出的。这一算法的详细描述和原理可以在论文《Decoupled Weight Decay Regularization》1中找到&#xff0c;该论文发表于2017年。在论文中&#xff0c;作者指出了传统Adam算法在权重衰减&#xff08;weight d…

初等数学几百年重大错误:将根本不是无穷集的真子集误为其真子集

黄小宁 【摘要】长为1的直线段形橡皮筋A拉长为长为2的橡皮筋B&#xff08;可二等分&#xff09;&#xff0c;去掉拉力使B缩短成原来的A&#xff0c;A不是B的一半。同样可证直线段L均匀压缩变短为直线段D&#xff5e;L不能成为L的一部分。数学一直误以为D是L的一部分使康脱推出…

C/C++栈和队列

一.队列 结构定义 FIFO:队列是一个先进先出的数据结构; 只允许从队首出元素,从队尾入元素; head和tail所包含的区间是左闭开的; 入队操作 没用真实将一号元素删除,而是将head指针向后移动一位,进行逻辑上的删除; 出队操作 将新元素储存在队尾指针所在的位置,并将队尾指针…

二校区图书馆一楼《中华再造善本》很多

上两幅为同一本书的&#xff0c;有“太平之时嫌官小&#xff0c;离乱之时怕出征”这句 上两幅为同一本书的&#xff0c;为《水浒传》节选 二校区图书馆一楼满眼都是线装的古书《中华再造善本》 图书馆五楼 图书馆四楼&#xff0c;一个人躺在长沙发上 图书馆一楼的透明电梯

Intel Xeon(至强) 服务器 CPU

Purley平台&#xff1a;Sky Lake&#xff08;第一代&#xff09;、Cascade Lake&#xff08;第二代&#xff09; Whitley平台&#xff1a;Cooper Lake、Ice Lake&#xff08;第三代&#xff09; Eagle Stream平台&#xff1a;Sapphire Rapids、Emerald Rapids&#xff08;第四…