Laravel Package for Matching Engine

快速开始

  • github地址
  • 安装: composer require sting_bo/mengine
  • 复制配置文件: php artisan vendor:publish

依赖

  • predis

号外

使用说明

  • 已有数据的系统如果使用此库,可以自己写一个初始化脚本,先把数据跑入队列

  • 用户下单

  • 下单后,先存入数据库,然后才开始下面步骤,实例化单据对象

use StingBo\Mengine\Core\Order;

$uuid = 3; // 用户唯一标识
$oid = 4; // 订单唯一标识
$symbol = 'abc2usdt'; // 交易对
$transaction = 'buy'; // 交易方向,buy/sale
$price = 0.4; // 交易价格,会根据设置精度转化为整数
$volume = 15; // 交易数量,会根据设置精度转化为整数 $order = new Order($uuid, $oid, $symbol, $transaction, $volume, $price);

交易方向交易精度可在配置文件灵活设置

return [
'mengine' => [
// 交易类型,不可更改
'transaction' => [
'buy',
'sale',
],
// 精度,可更改
'accuracy' => 8, //default
'test2usdt_accuracy' => 4, //设置交易对精度则使用,没有则取accuracy
],
];
  • push到队列,队列任务需要手动开启
use StingBo\Mengine\Services\MengineService;

$ms = new MengineService();
$ms->pushQueue($order);

开启队列任务:

php artisan queue:work --queue=abc2usdt

也可以使用horizonsupervisor来辅助,事半功倍!

队列消费时会进入撮合程序,大概的步骤如下:

  1. 获取匹配委托订单
  2. 如果没有匹配的订单,则进入委托池,触发委托池变更事件,详见第5点
  3. 如果有匹配的委托,程序撮合,更新委托池数据
  4. 交易成功会触发事件,开发者要在监听器里处理有交易的委托单,比如更新数据库数据,WebSocket通知等

    在EventServiceProvider里为撮合成功的事件注册监听器:
// 撮合成功通知,参数分别是:当前订单,被匹配的单据,交易数量
event(new MatchEvent($order, $match_order, $match_volume)); // 注册监听器
protected $listen = [
'StingBo\Mengine\Events\MatchEvent' => [
'App\Listeners\YourListener', // 你自己的监听器,应该也使用异步来实现
],
];
  1. 如果只是部分成交,则剩余部分进入委托池,触发委托池变更事件,K线或者深度列表变更通知等,

    注册监听器如下:
// 委托池数据变更事件
event(new PushQueueEvent($order)); // 注册监听器
protected $listen = [
'StingBo\Mengine\Events\PushQueueEvent' => [
'App\Listeners\YourListener', // 你自己的监听器,应该也使用异步来实现
],
];
  • 用户撤单

撤单流程应该是先查询数据库确认是否可撤销,再从redis里删除数据成功,最后更新回数据库

$order = new Order($uuid, $oid, $symbol, $transaction, $volume, $price);
$ms = new MengineService();
$ms->deleteOrder($order);

此撮合引擎没有实现像数据库那样的锁机制,为了防止有单子在被撮合时又有撤销的命令出现,所以下单与撤单都走的同一个队列,保证了顺序性,每个交易对是隔离的队列,效率也有一定的保证,但开发需要实现异步通知用户功能,注册监听器如下:

// 撤单成功通知
event(new DeleteOrderSuccEvent($order)); // 注册监听器
protected $listen = [
'StingBo\Mengine\Events\DeleteOrderSuccEvent' => [
'App\Listeners\YourListener', // 你自己的监听器,应该也使用异步来实现
],
];
  • 获取某个交易对买/卖深度列表

$symbol = 'abc2cny';
$transaction = 'buy';
$ms = new MengineService();
$ms->getDepth($symbol, $transaction);

总结

本地垃圾笔记本上测试,交易对撮合速度平均在200笔/s,后续将继续优化撮合速度

Matching Engine For Laravel(基于redis的撮合引擎),PHP高性能撮合引擎的更多相关文章

  1. laravel基于redis实现的一个简单的秒杀系统

    说明:网上很多redis秒杀系统的文章,看的都是一头雾水,然后自己来实现一个,也方便以后自己学习 实现的方式是用的redis的list队列,框架为laravel 核心部分为list的pop操作,此操作 ...

  2. [原创]Laravel 基于redis队列的解析

    目录 参考链接 本文环境 为什么使用队列 Laravel 中的队列 分发任务 任务队列 Worker Last-Modified: 2019年5月10日11:44:18 参考链接 使用 Laravel ...

  3. Gome 高性能撮合引擎微服务

    Gome 高性能撮合引擎微服务 使用 Golang 做计算,gRPC 做服务,ProtoBuf 做数据交换,RabbitMQ 做队列,Redis 做缓存实现的高性能撮合引擎微服务 依赖 具体依赖信息可 ...

  4. PHP【Laravel】delayer基于redis的实现订单超时改变状态

    实现这个功能前你需要知道以下,不然可能会比较吃力:1.服务器的计划任务,shell脚本,或者你有宝塔自带的计划任务会方便很多.2.有所了解Redis.3.会写PHP业务逻辑. 好了进入在正题,这里使用 ...

  5. 基于redis排行榜的实战总结

    前言: 之前写过排行榜的设计和实现, 不同需求其背后的架构和设计模型也不一样. 平台差异, 有的立足于游戏平台, 为多个应用提供服务, 有的仅限于单个游戏.排名范围差异, 有的面向全局排名, 有的只做 ...

  6. 消息中心 - Laravel的Redis队列(一)

    前言 Laravel的队列可以用在轻量级的队列需求中.比如我们系统中的短信.邮件等功能,这些功能有一些普遍的特征,异步.重试.并发控制等.Laravel现在主要支持的队列服务有Null.Sync.Da ...

  7. redixdb 基于redis 协议的实时key-value 存储

    redixdb 是一个基于redis 协议搞的一个实时key value 处理的轻量级应用,支持多种后端 存储模型. 以下是一个小版的容器镜像(官方的太大了) dockerfile   FROM go ...

  8. 基于redis的处理session的方法

    一个基于redis的处理session的方法,如下. <?php class Session_custom { private $redis; // redis实例 private $prefi ...

  9. 基于redis 实现分布式锁的方案

    在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...

随机推荐

  1. (三)React Ant Design Pro + .Net5 WebApi:后端环境搭建

    一. 简介 1. 平常用的core webapi 3.1,恰逢.Net5.0正式版发布了,直接开整. 2. 先学习IdentityServer4 .Autofac.EF Core,集成到后台框架里. ...

  2. C#数组的 Length 和 Count()

    C#数组的 Length 和 Count() C# 数组中 Length 表示数组项的个数,是个属性.而 Count() 也是表示项的个数,是个方法,它的值和 Length 一样.但实际上严格地说, ...

  3. URL重定向 - Pikachu

    概述: 不安全的url跳转问题可能发生在一切执行了url地址跳转的地方.如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的话就可能 ...

  4. ctfhub技能树—信息泄露—git泄露—Log

    什么是git泄露? 当前大量开发人员使用git进行版本控制,对站点自动部署.如果配置不当,可能会将.git文件夹直接部署到线上环境.这就引起了git泄露漏洞. 打开靶机环境 查看网页内容 使用dirs ...

  5. SpringBoot WebSocket技术

    最近看了Spring in Action,了解了一下WebSocket和Stomp协议相关技术,并搭建了一个项目.网上的例子不完整或者描述不清,所以自己记录一下以作备忘. 一.配置 Spring Bo ...

  6. Java安全之Weblogic 2018-3248分析

    Java安全之Weblogic 2018-3248分析 0x00 前言 基于前面的分析,后面的还是主要看补丁的绕过方式,这里就来简单的记录一下. 0x01 补丁分析 先来看看补丁细节 private ...

  7. STM32F207时钟系统解析

    在前几天的文章<晶振原理解析>中介绍了晶振如何产生时钟的,板子使用的是25M无源晶振,下文将介绍STM32F207的时钟系统如何将25M晶振时钟转换为120M系统主频时钟的. 01.时钟系 ...

  8. CentOS 7.2系统安装步骤

    CentOS 7.2系统安装步骤 1.把系统U盘插到服务器上,然后启动服务器进入BIOS界面选择U盘启动. 根据服务器的不同,进入BIOS界面的按钮也不一样,主流的有F10.F11.F12.F2.ES ...

  9. 浅析Redis与IO多路复用器原理

    为什么Redis使用多路复用I/O Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导 ...

  10. Redis集群数据没法拆分时的搭建策略

    在上一篇文章中,针对服务器单点.单例.单机存在的问题: 单点故障 容量有限 可支持的连接有限(性能不足) 提出了解决的办法:根据AKF原则搭建集群,大意是先X轴拆分,创建单机的镜像,组成主主.主备.主 ...