PHP使用SWOOLE擴充實現定時同步

來源:互聯網
上載者:User
本文給大家介紹的是一次比較特殊的任務,我們使用PHP SWOOLE 做一個非同步定時任務系統,具體如何來實現的呢,接下來來我們好好看下吧

南寧公司和幾個分公司之間都使用了呼叫系統,然後現在需要做一個呼叫通話資料分析,由於分公司的呼叫伺服器是在內網,通過技術手段映射出來,分公司到南寧之間的網路不穩定,所以需要把分公司的通話資料同步到南寧。

本身最簡單的方法就是直接配置MySQL的主從同步就可以同步資料到南寧來了。但是銷售呼叫系統那邊的公司不給MySQL許可權我們。 所以這個方法只能放棄了。

於是我們乾脆的想,使用PHP來實現定時一個簡易的PHP定時同步工具,然後PHP進程常駐後台運行,所以首先就先到了一個PHP組件:SWOOLE,經過討論,分公司的每天半天產生的資料量最大在5000條左右,所以這個方案是可行,就這樣幹。

我們使用PHP SWOOLE 做一個非同步定時任務系統。

本身MySQL資料庫的主從同步是通過解析Master庫中的binary-log來進行同步資料到從庫的。然而我們使用PHP來同步資料的時候,那麼只能從master庫分批查詢資料,然後插入到南寧的slave庫來了。

這裡我們使用的架構是 ThinkPHP 3.2 .

首先安裝PHP擴充: SWOOLE,因為沒有使用到特別的功能,所以這裡我們使用pecl來快速安裝:

pecl install swoole

安裝完成後在 php.ini 裡面加入 extension="swoole.so" 安裝完成後,我們使用 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/bashPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport 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: 最好推薦在裡面加入寫日誌操作,這樣好知道是任務推送、執行是否成功。

至此基本完成,程式有待最佳化~~~,各位看客有更好的方法歡迎提出。

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.