coinex // 撮合引擎 逻辑流程 (两种数据源 初始化源和前端源)

news2024/9/21 14:50:44

目录

1 生产者 数据源

1.1. match-server 一启动 初始化数据 自动查询数据库 查询level2要展示的数据

1.2 match-server接收 前端发给Exchange-server的数据

2. 将查询/接受的数据EntrustOrder 转成 Order 解耦 过滤掉不要的属性

3.Order转成 OrderEvent

4. 分配序号发布数据到ringbuffer,管理序号和栅栏(前提是ringbuffer构建好了)

5 分配序号 发布数据到ringbuffer

5.1. 初始化数据源实现的代码 循环每一条数据转换 分配序号 发布数据到ringbuffer

5.2 前端数据源


1 生产者 数据源

1.1 match-server 一启动 初始化数据 自动查询数据库 查询level2要展示的数据

List<EntrustOrder> entrustOrders = entrustOrderMapper.selectList(
                new LambdaQueryWrapper<EntrustOrder>()
                        .eq(EntrustOrder::getStatus, 0)
                        .orderByAsc(EntrustOrder::getCreated)

1.2 match-server接收 前端发给Exchange-server的数据

 @StreamListener("order_in") // "order_in" 在 Sink中
    public void handleMessage(EntrustOrder entrustOrder) { // 消息监听}

2. 将查询/接受的数据EntrustOrder 转成 Order 解耦 过滤掉不要的属性

public static  Order entrustOrder2Order(EntrustOrder entrustOrder) {
        Order order = new Order();
        order.setOrderId(entrustOrder.getId().toString());

        order.setPrice(entrustOrder.getPrice());
        order.setAmount(entrustOrder.getVolume().subtract(entrustOrder.getDeal())); // 交易的数量= 总数量- 已经成交的数量

        order.setSymbol(entrustOrder.getSymbol());
        order.setOrderDirection(OrderDirection.getOrderDirection(entrustOrder.getType().intValue())); // 交易side
        order.setTime(entrustOrder.getCreated().getTime());

        return order ;

    }

3.Order转成 OrderEvent

// 使用事件转换器的好处,1环形队列获取序号, 2拿到事件填充数据, 3再发布序号 省了从2给 事件填充数据 private static final EventTranslatorOneArg<OrderEvent, Order> TRANSLATOR = new EventTranslatorOneArg<OrderEvent, Order>() { // Order 转化成 OrderEvent
        // 现在上面实例化 然后 在下面 实现

        /**
         * Translate a data representation into fields set in given event 将数据表示转换为给定事件中设置的字段
         * Params:参数
         * event
         *  into which the data should be translated. 要转成什么data
         * sequence 序列
         * that is assigned to event. 分配给事件的序列。
         * arg0
         * The first user specified argument to the translator 转换器的第一个用户指定参数
         */
        public void translateTo(OrderEvent event, long sequence, Order input) {
            event.setSource(input);
        } // setSource 是 source的 set方法
    };

4. 分配序号发布数据到ringbuffer,管理序号和栅栏(前提是ringbuffer构建好了)

/**
     * 我们使用DisruptorTemplate 时,就使用它的onData方法
     * @param input
     *
     * public <A> void publishEvent(EventTranslatorOneArg<E, A> translator, A arg0)
     *     {
     *         final long sequence = sequencer.next();
     *         translateAndPublish(translator, sequence, arg0);
     *     }
     * private <A> void translateAndPublish(EventTranslatorOneArg<E, A> translator, long sequence, A arg0)
     *     {
     *         try
     *         {
     *             translator.translateTo(get(sequence), sequence, arg0);
     *         }
     *         finally
     *         {
     *             sequencer.publish(sequence);
     *         }
     *     }
     *
     *     void publish(long sequence);
     *
     */
    public void onData(Order input) {
        ringBuffer.publishEvent(TRANSLATOR, input); // 这个就是分配序号 然后发布数据到ringbuffer
    }

5 分配序号 发布数据到ringbuffer

5.1. 初始化数据源 从数据查询数据 循环每一条数据转换 分配序号 发布数据到ringbuffer

for (EntrustOrder entrustOrder : entrustOrders) {
            disruptorTemplate.onData(BeanUtils.entrustOrder2Order(entrustOrder)); // 往ringbuffer 中放 // BeanUtils.entrustOrder2Order 数据转换
        } // BeanUtils.entrustOrder2Order(entrustOrder) 是数据转换 就是从entrustOrder  筛选出 Order 需要的属性数据

5.2 前端数据源 高频多生产者 每次一条数据

exchange-service 发送消息到match

disruptorTemplate.onData(BeanUtils.entrustOrder2Order(entrustOrder));

6 disruptorTemplate.onData 源码

onData

public void onData(Order input) {
         ringBuffer.publishEvent(TRANSLATOR, input); // 这个就是分配序号 然后发布数据到ringbuffer
          }

TRANSLATOR

// 先用 EventTranslatorOneArg方法做了个 TRANSLATOR 再调用publishEvent方法
private static final EventTranslatorOneArg<OrderEvent, Order> TRANSLATOR = new EventTranslatorOneArg<OrderEvent, Order>() { // Order 转化成 OrderEvent

        public void translateTo(OrderEvent event, long sequence, Order input) {
            event.setSource(input);
        } // setSource 是 source的 set方法
    };

publishEvent

@Override
    public <A> void publishEvent(EventTranslatorOneArg<E, A> translator, A arg0)
    {
        final long sequence = sequencer.next(); // 单生成者就是 但生产者中得next算法 1:43:28 // https://www.bilibili.com/video/BV1zM4y1L7Q9/?spm_id_from=333.337.search-card.all.click&vd_source=ff8b7f852278821525f11666b36f180a
        translateAndPublish(translator, sequence, arg0);
    }

 translateAndPublish

private <A> void translateAndPublish(EventTranslatorOneArg<E, A> translator, long sequence, A arg0)
    {
        try
        {
            translator.translateTo(get(sequence), sequence, arg0);
        }
        finally
        {
            sequencer.publish(sequence);
        }
    }

EventTranslatorOneArg 

public interface EventTranslatorOneArg<T, A>
{
    /**
     * Translate a data representation into fields set in given event
     *
     * @param event    into which the data should be translated.
     * @param sequence that is assigned to event.
     * @param arg0     The first user specified argument to the translator
     */
    void translateTo(T event, long sequence, A arg0);
}

translateTo 自定义 还是调用?

private static final EventTranslatorOneArg<OrderEvent, Order> TRANSLATOR = new EventTranslatorOneArg<OrderEvent, Order>() { // Order 转化成 OrderEvent
        public void translateTo(OrderEvent event, long sequence, Order input) {
            event.setSource(input);
        } // setSource 是 source的 set方法
    };

Sequencer

public interface Sequencer extends Cursored, Sequenced
{
}

Sequenced ->publish

public interface Sequenced
{
    /**
     * Publishes a sequence. Call when the event has been filled.
     *
     * @param sequence the sequence to be published.
     */
    void publish(long sequence); // 操作: publish 序号
}

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

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

相关文章

【初学ROS,年轻人的第一个Node节点】

【初学ROS&#xff0c;年轻人的第一个Node节点】 1. 工作空间设置2. 创建Package3. 回访依赖包4. 创建Node节点5. 源码编译6. 运行Node节点7. Node节点完善8. 总结 本教程是B站阿杰视频的笔记 视频地址&#xff1a;https://www.bilibili.com/video/BV1nG411V7HW 超声波传感器 …

界面组件DevExtreme v22.2新版亮点 - 各UI组件增强升级

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…

geometric distribution and exponential distribution(几何分布和指数分布)

几何分布 分布函数均值和方差意义 表示经过k次实验才第一次得到正确的实验结果 比如抛硬币得到正面的需要抛的次数 指数分布 分布函数均值和方差意义 表示经过一段x之后&#xff0c;某件事第一次发生 比如经过x时间之后&#xff0c;公交车来的概率 比如餐厅从开业到第一个客人…

基于ArcGIS 服务获取气象栅格某点位值及数据更新

1. 背景 假如有很多气象数据&#xff0c;不想通过后台脚本去获取数据&#xff0c;想通过前台服务的rest接口去识别&#xff0c;并且这些栅格数据可能是需要更新变化的&#xff0c;以下对一些技术方法做一个简单的介绍。 需求概述&#xff1a; 点击某一个点&#xff0c;获取影…

设计模式 --- 概述

一、设计模式概述 1.1、软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任 克里斯托夫亚历山大 &#xff08;Christopher Alexander&…

c/c++:三维数组,字符数组和字符串,统计字符串中字符出现的频次,scanf输入空格,正则匹配表达式

c/c:三维数组&#xff0c;字符数组和字符串&#xff0c;统计字符串中字符出现的频次&#xff0c;scanf输入空格&#xff0c;正则匹配表达式 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;此时学会c的话&#xff0c; 我所知…

WPF教程(十一)---数据绑定(4)--数据类绑定

一、排序 如果想以特定的方式对数据进行排序&#xff0c;可以绑定到 CollectionViewSource&#xff0c;而不是直接绑定到 ObjectDataProvider。CollectionViewSource 则会成为数据源&#xff0c;并充当截取 ObjectDataProvider 中的数据的媒介&#xff0c;并提供排序、分组和筛…

PMP项目管理-[第六章]进度管理

进度管理知识体系&#xff1a; 规划进度管理&#xff1a; 定义活动&#xff1a; 排列活动顺序&#xff1a; 估算活动持续时间&#xff1a; 制定进度计划&#xff1a; 6.1 规划进度管理 定义&#xff1a;为规划、编制、管理、执行和控制项目进度而制定政策、程序和文档的过程 作…

docker简单教程(三)常用操作

docker简单教程&#xff08;三&#xff09;常用操作 文章目录 docker简单教程&#xff08;三&#xff09;常用操作1&#xff1a;查看所有容器列表&#xff1a;docker ps -a2&#xff1a;查看正在运行的容器列表&#xff1a;docker ps3&#xff1a;运行容器&#xff1a;docker r…

内网渗透之横向移动wmismb密码喷射CrackMapExec

0x01 横向移动之wmi wmi可以通过hash或明文进行验证&#xff0c;不会在系统日志中留下痕迹&#xff0c;使用139端口 复现环境&#xff1a; god.org win2008 dc win2012sql win2008 web 准备&#xff1a; cs上线 win2008web 提权利用ms14-058 抓取hash和明文密码(当获取到其他…

重磅发布,时隔两月——复旦大学MOSS最新0.0.3版本发布

今天中午吃饭的时候无意间看到一则新闻说的就是复旦大学开发的MOSS也就是国产版的类chatGPT对话模型已经发布了最新版本0。0.3&#xff0c;目前公测期间是完全开源免费的&#xff0c;还是可以上手体验一下的。 官方的博客介绍在这里&#xff0c;首页如下所示&#xff1a; 如果…

手机端无线投屏技术及方案推荐

目前主流的无线投屏技术主要又DLNA&#xff0c;Miracast&#xff0c;Airplay。 对协议的描述引用知乎作者的文章&#xff0c;原文&#xff1a;AirPlay、Miracast 、DLNA三大协议对比 - 知乎 (zhihu.com) 【DLNA】 DNLA&#xff0c;Digital Living Network Alliance&#xff…

光照的个人推导过程与GL实现

目录 1、前提知识 1.1、GL的绘图过程&#xff1a; 1.2、点积的规则和作用&#xff1a; 1.3、normalize在方向处理上的作用 2、光照控制的理论基础 2.1、自由的实现&#xff1a; 2.2、带有方向性的光——基于dot product的实现 最终效果演示如下&#xff1a; 3、关键代…

可能是史上最详细的MySQL用户和权限原理和实战

前言 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database Management System&#xff0c;关系…

Python - Jupyter - 远程连接Jupyter内核

Python - Jupyter - 远程连接Jupyter内核 前言 假设你有一台高性能服务器&#xff08;电脑B&#xff09;&#xff0c;并且在上面安装好了Jupyter 现在你想使用你自己常用的电脑&#xff08;电脑A&#xff09;编码&#xff0c;但使用电脑B的计算资源。 怎么办呢&#xff1f;…

WPS以普通会员价格升级超级会员

文章目录 一、新会员体系二、基本原理三、升级超级会员1、购买会员时长2、成功通知3、兑换时长 一、新会员体系 4月17日&#xff0c;WPS会员体系全新升级。本次升级&#xff0c;WPS将原“WPS会员”、“稻壳会员”及“超级会员”合并、升级&#xff0c;推出全新的“WPS超级会员…

235:vue+openlayers 绘制带有径向渐变填充色的圆形

第235个 点击查看专栏目录 本示例的目的是介绍如何在vue+openlayer中绘制带有径向渐变填充色的圆形。 如果填充线性渐变的多边形,可以参考这个篇文章 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共136行)相关A…

通过python代码自定义ssh密码爆破

通过python代码自定义ssh密码爆破 一&#xff0c;这段代码的意义&#xff1a;二&#xff0c;直接上写好的代码:三&#xff0c;使用pip3 install paramiko 命令安装库四&#xff0c;使用 python3 test.py 主机地址 -u 用户名 -p 字典路径/五&#xff0c;字典的选取 一&#xff0…

RT-DETR的学习笔记

1. RT-DETR GitHub: PaddleDetection/tree/develop/configs/rtdetr 2. 复现训练流程 2.1 原文使用设备 2.2 环境要求 4*v100 cuda 10.2 paddlepaddle-gpu > 2.4.1 2.3 创建conda环境 conda create --name ppdet python3.102.4 安装RT-DETR推荐的paddle版本 前往官网…

4.26和4.27、selectAPI介绍(4.27、select代码)

4.26和4.27、selectAPI介绍&#xff08;4.27、select代码&#xff09; 1.selectAPI介绍①select多路复用流程图②select多路复用缺点 2.select代码使用介绍3.select代码实现①select服务端实现②select客户端实现 1.selectAPI介绍 主旨思想&#xff1a; 首先要构造一个关于文件…