首 页最新软件下载排行文章资讯投稿发布下载专题
维维下载站
您的位置:首页编程开发网络编程PHP编程 → PHP如何利用SWOOLE扩展实现定时同步例子分享

PHP如何利用SWOOLE扩展实现定时同步例子分享

来源:维维整理 发布时间:2017-4-9 18:45:32 人气:

今天要给大家分享的是PHP如何利用SWOOLE扩展实现定时同步例子分享,本文主要介绍的是一次有些特殊的任务,我们使用PHP SWOOLE 做一个异步的定时任务系统,那么具体要怎么来实现的呢,来看看下面的详细介绍吧。

呼叫系统在南宁和几个分支之间使用,但现在有必要进行呼叫数据分析,因为分支的分支服务器在内联网上,通过技术手段映射,并且分支到南宁之间的网络。它不稳定,因此需要将分支的呼叫数据同步到南宁。

最简单的方法是直接配置MySQL的主从同步以将数据同步到Nanning。但是,销售呼叫系统的公司不会向我们授予MySQL许可。所以这种方法只能放弃。

所以我们只想用PHP来实现一个简单的PHP定时同步工具,然后PHP进程在后台运行,所以首先来一个PHP组件:SWOOLE,经过讨论,分支每天生成最大量的数据半天。大约5,000,所以这个程序是可行的,就这样做。

我们使用PHP SWOOLE来执行异步定时任务系统。

MySQL数据库本身的主从同步是通过解析主库中的二进制日志来将数据同步到从库。但是,当我们使用PHP同步数据时,我们只能批量查询主库中的数据,然后将其插入到南宁的从库中。

这里使用的框架是ThinkPHP 3.2

首先安装PHP扩展:SWOOLE,因为我们不使用特殊功能,所以这里我们使用pecl快速安装:

Pecl安装swoole

安装完成后,将extension =“swoole.so”添加到php.ini。安装完成后,我们使用phpinfo()来检查它是否成功。

安装成功了,我们就来写业务。

服务端

1、首先启动一个后台的服务端,监听端口9501
 
public function index()
{
 $serv = new \swoole_server("0.0.0.0", 9501);
 $serv->set([
  'worker_num' => 1,//一般设置为服务器CPU数的1-4倍
  'task_worker_num' => 8,//task进程的数量
  'daemonize' => 1,//以守护进程执行
  'max_request' => 10000,//最大请求数量
  "task_ipc_mode " => 2 //使用消息队列通信,并设置为争抢模式
 ]);
 $serv->on('Receive', [$this, 'onReceive']);//接收任务,并投递
 $serv->on('Task', [$this, 'onTask']);//可以在这个方法里面处理任务
 $serv->on('Finish', [$this, 'onFinish']);//任务完成时候调用
 $serv->start();
}

2、接收和投递任务

public function onReceive($serv, $fd, $from_id, $data)
{
 //使用json_decode 解析任务数据
 $areas = json_decode($data,true);
 foreach ($areas as $area){
  //投递异步任务
  $serv->task($area);
 }
}

3、任务执行,数据从master库查询和写入到slave数据库

public function onTask($serv, $task_id, $from_id, $task_data)
{
 $area = $task_data;//参数是地区编号
 $rows = 50; //每页多少条
 //主库地址,根据参数地区($area)编号切换master数据库连接
 //从库MySQL实例,根据参数地区($area)编号切换slave数据库连接
 //因为程序是常驻内存的,因此MySQL连接能够使用长连接,接着重复利用。要使用设计模式的,能够使用对象池模式
 Code......
 
 //master 库为分公司的数据库,slave库为数据同步到南宁后的从库
 Code......
 
 //使用$sql获取从库中最大的自增: SELECT MAX(id) AS maxid FROM ss_cdr_cdr_info limit 1
 $slaveMaxIncrementId = ...;
 
 //使用$sql获取主库中最大的自增: SELECT MAX(id) AS maxid FROM ss_cdr_cdr_info limit 1
 $masterMaxIncrementId = ...;
 
 //如果相等的就不同步了
 if($slaveMaxIncrementId >= $masterMaxIncrementId){
  return false;
 }
 
 //根据条数计算页数
 $dataNumber = ceil($masterMaxIncrementId - $slaveMaxIncrementId);
 $eachNumber = ceil($dataNumber / $rows);
 $left = 0;
 
 //根据页数来进行分批循环进行写入,要记得及时清理内存
 for ($i = 0; $i < $eachNumber; $i++) {
  $left = $i == 0 ? $slaveMaxIncrementId : $left + $rows;
  $right = $left + $rows;
  //生成分批查询条件
  //$where = "id > $left AND <= $right";
  $masterData = ...;//从主库查询数据
  $slaveLastInsertId = ...;//插入到从库
  unset($masterData,$slaveLastInsertId);
 }
 
 echo "New AsyncTask[id=$task_id]".PHP_EOL;
 $serv->finish("$area -> OK");
}

4、任务完成时候调用
 
public function onFinish($serv, $task_id, $task_data)
{
 echo "AsyncTask[$task_id] Finish: $task_data".PHP_EOL;
}

客户端推送任务

此此基本算是完成了,剩下来的我们来写客户端任务推送

public function index()
{
 $client = new \swoole_client(SWOOLE_SOCK_TCP);
 if (!$client->connect('127.0.0.1', 9501, 1)) {
  throw new Exception('链接SWOOLE服务错误');
 }
 $areas = json_encode(['liuzhou','yulin','beihai','guilin']);
 //开始遍历检查
 $client->send($areas);
 echo "任务发送成功".PHP_EOL;
}

到这基本完成了,剩下的来写一个shell脚本定时执行:/home/wwwroot/sync_db/crontab/send.sh
 
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
# 定时推送异步的数据同步任务
/usr/bin/php /home/wwwroot/sync_db/server.php home/index/index
 

使用crontab定时任务,我们把脚本加入定时任务
 
#设置每天12:30执行数据同步任务
30 12 * * * root /home/wwwroot/sync_db/crontab/send.sh
#设置每天19:00执行数据同步任务
0 19 * * * root /home/wwwroot/sync_db/crontab/send.sh

Tips: 最好推荐在里面加入写日志操作,这样好知道是任务推送、执行是否成功。

相关下载
栏目导航
本类热门阅览