この記事では、PHP SWOOLE を使用して非同期スケジュールされたタスク システムを作成する方法を紹介します。
Nanning Company では、呼び出しシステムを使用しています。支店の通話サーバーはイントラネット上にあり、技術的な手段でマッピングされているため、支店と南寧間のネットワークが不安定であるため、通話データを分析する必要があります。南寧と同期します。
最も簡単な方法は、MySQL のマスター/スレーブ同期を直接設定してデータを Nanning に同期することです。しかし、営業電話システムの会社は私たちに MySQL 権限を与えません。したがって、この方法は放棄するしかありません。
そこで、PHP を使用して単純な PHP タイミング同期ツールを実装することを考えました。その後、PHP プロセスがバックグラウンドで実行されるため、最初に PHP コンポーネントである SWOOLE にたどり着きました。議論の結果、The Branch Company が設立しました。半日で生成されるデータの最大量は約 5,000 なので、この解決策は実現可能ですので、ぜひ実行してください。
PHP SWOOLE を使用して非同期スケジュール タスク システムを作成します。
MySQL データベース自体のマスター/スレーブ同期は、マスター データベース内のバイナリ ログを解析することによって、データをスレーブ データベースに同期します。ただし、PHP を使用してデータを同期する場合、マスター ライブラリからデータをバッチでクエリし、それを南寧のスレーブ ライブラリに挿入することしかできません。
ここで使用するフレームワークは ThinkPHP 3.2
です。
最初に PHP 拡張機能 SWOOLE をインストールします。特別な関数は使用しないため、ここでは簡単にインストールするために pecl を使用します。 :
pecl install swoole
インストールが完了したら、extension="swoole.so"
を php.ini
に追加します。インストールが完了したら、phpinfo()
を使用して、インストールが成功したかどうかを確認します。ビジネスを書きます。
サーバー
1. まずバックグラウンド サーバーを起動し、ポート 9501public 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. タスクの実行、データがクエリされ、マスター データベースからスレーブ データベースに書き込まれます。
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"); }
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; }
#!/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
#
#设置每天12:30执行数据同步任务 30 12 * * * root /home/wwwroot/sync_db/crontab/send.sh #设置每天19:00执行数据同步任务 0 19 * * * root /home/wwwroot/sync_db/crontab/send.sh
PHHPMyadmin エクスポート機能を模倣し、PHP を使用して MySQL データベースを .sql ファイルとしてエクスポートします
# #thinkphp5 について、および swoole が SMTP を介して非同期大量メール送信を実装する方法の詳細な説明
以上がPHP を使用して SWOOLE 拡張機能を有効にして MySQL データを定期的に同期する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。