这里主要是一个生成高开低收四个数值的脚本,已生成的保存到数据库,最后一条不确定的在redis
1,测试数据的表结构,建在basedata数据库下面
CREATE TABLE `hedge_basis_mode` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`interval` enum('5m','1h','1d') NOT NULL DEFAULT '5m' COMMENT '间隔 5m=5分钟;1h=1小时;1d=1天',`path` varchar(100) NOT NULL COMMENT '路径',`mode` enum('ab','ba') NOT NULL DEFAULT 'ab' COMMENT '方式 ab或ba',`open` decimal(10,6) NOT NULL COMMENT '开',`close` decimal(10,6) NOT NULL COMMENT '收',`tallest` decimal(10,6) NOT NULL COMMENT '高',`lowest` decimal(10,6) NOT NULL COMMENT '低',`create_time` bigint(13) unsigned NOT NULL COMMENT '创建时间',PRIMARY KEY (`id`),KEY `lianhe` (`interval`,`path`,`mode`,`create_time`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2713 DEFAULT CHARSET=utf8mb4
2,生成测试数据的脚本,需要swoole扩展
<?php/*** 1,生成ab,ba,time数据* 2,根据时间插入到数据库,并把最新的放到redis*/class TestC
{protected $path;protected $data;protected $modeList;protected $interval;protected $vls;protected $sec;protected $db;protected $rs;public function __construct($path = null){$this->modeList = ['ab','ba'];$this->interval = ['5m','1h','1d'];$this->sec = ['5m'=>5*60*1000,'1h'=>60*60*1000,'1d'=>60*60*24*1000];$this->vls = ['open','close','tallest','lowest'];$this->path = $path;}public function getPathList(){return ['btc','ltc','eth',];}public function run(){foreach ($this->getPathList() as $path) {$this->test(new self($path),'put','hello');}}public function test($obj,$fun,...$params){\Swoole\Runtime::enableCoroutine();\Swoole\Coroutine::create(function()use($obj,$fun,$params){$obj->{$fun}($params);});}public function put($params){while(true){$one = $this->getOne();$this->formatData($one);\Swoole\Coroutine\System::sleep(mt_rand(1,10) / 10);}}public function getOne(){$path = $this->path;if(mt_rand(1,2) == 1){$ab = mt_rand(1,10000) / 10000;}else{$ab = (mt_rand(1,10000) / 10000) * -1 ;}$ba = $ab * -1;$time = time() * 1000;return compact('path','ab','ba','time');}public function formatData($data){//如果第一次,就初始化if(empty($this->data)){echo "初始化{$this->path} ".date('Y-m-d H:i:s')."\n"; foreach ($this->interval as $interval) {foreach ($this->modeList as $mode) {foreach ($this->vls as $vl) {$this->data[$interval][$mode][$vl] = $data[$mode];}}$this->data[$interval]['time'] = $data['time'];}//如果不是,则比较}else{foreach ($this->interval as $interval) {//进入新的时间间隔if($data['time'] - $this->data[$interval]['time'] >= $this->sec[$interval]){echo "进入新的时间间隔{$interval}_{$this->path}_{$data['time']}_{$this->data[$interval]['time']}_{$this->sec[$interval]}\n";foreach ($this->modeList as $mode) {$this->save($interval,$mode);foreach ($this->vls as $vl) {$this->data[$interval][$mode][$vl] = $data[$mode];}}$this->data[$interval]['time'] = $data['time'];}foreach ($this->modeList as $mode) {$this->data[$interval][$mode]['close'] = $data[$mode];if($data[$mode] > $this->data[$interval][$mode]['tallest']){$this->data[$interval][$mode]['tallest'] = $data[$mode];}if($data[$mode] < $this->data[$interval][$mode]['lowest']){$this->data[$interval][$mode]['lowest'] = $data[$mode];}$this->pushRedis($interval,$mode);}}}}//发布到redis,后面会用websocket服务订阅这里的数据,有更新就传给前端绘图public function pushRedis($interval,$mode){if(empty($this->rs)){$redis = new \Swoole\Coroutine\Redis();$redis->connect('127.0.0.1', 6379);$this->rs = $redis;}$rkey = "zl_{$mode}_{$interval}_{$this->path}";$data = ['time' => $this->data[$interval]['time'],'open' => $this->data[$interval][$mode]['open'],'close' => $this->data[$interval][$mode]['close'],'tallest'=> $this->data[$interval][$mode]['tallest'],'lowest' => $this->data[$interval][$mode]['lowest']];$this->rs->publish($rkey,"'".json_encode($data)."'");}public function getDb(){if(empty($this->db)){$swoole_mysql = new \Swoole\Coroutine\MySQL();$swoole_mysql->connect(['host' => '127.0.0.1','port' => 3306,'user' => 'root','password' => '','database' => 'basedata',]);$this->db = $swoole_mysql;}}//保存到数据库public function save($itl,$mod){$this->getDb();$stmt = $this->db->prepare("insert into hedge_basis_mode(`interval`,`path`,`mode`,`open`,`close`,`tallest`,`lowest`,`create_time`) value(?,?,?,?,?,?,?,?)");$interval = $itl;$path = $this->path;$mode = $mod;$open = $this->data[$interval][$mode]['open'];$close= $this->data[$interval][$mode]['close'];$tallest= $this->data[$interval][$mode]['tallest'];$lowest= $this->data[$interval][$mode]['lowest'];$create_time = $this->data[$interval]['time'];if($stmt != false){$saveData = [$interval,$path,$mode,$open,$close,$tallest,$lowest,$create_time];if($stmt->execute($saveData) === false){echo "插入数据失败!".$this->db->error;}}}
}(new TestC())->run();
3,上面的数据库,表,swoole扩展都建好之后,把redis开启,然后执行上面的代码,别退出