ホームページ > バックエンド開発 > PHPチュートリアル > PHP を使用して SWOOLE 拡張機能を有効にして MySQL データを定期的に同期する方法

PHP を使用して SWOOLE 拡張機能を有効にして MySQL データを定期的に同期する方法

不言
リリース: 2023-03-31 13:38:01
オリジナル
1635 人が閲覧しました

この記事では、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. まずバックグラウンド サーバーを起動し、ポート 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. タスクの実行、データがクエリされ、マスター データベースからスレーブ データベースに書き込まれます。

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(&#39;127.0.0.1&#39;, 9501, 1)) {
  throw new Exception(&#39;链接SWOOLE服务错误&#39;);
 }
 $areas = json_encode([&#39;liuzhou&#39;,&#39;yulin&#39;,&#39;beihai&#39;,&#39;guilin&#39;]);
 //开始遍历检查
 $client->send($areas);
 echo "任务发送成功".PHP_EOL;
}
ログイン後にコピー

これで基本的には完了です。残りは、定期的に実行するシェル スクリプトを作成します: /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
ログイン後にコピー

ヒント: タスクがプッシュされたかどうかを確認できるように、ログ書き込み操作をスクリプトに追加することをお勧めします。そして実行は成功します。

これで基本的には完成しました。プログラムを最適化する必要があります~~~。もっと良い方法があれば、ぜひ提案してください。

上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。

関連する推奨事項:

PHHPMyadmin エクスポート機能を模倣し、PHP を使用して MySQL データベースを .sql ファイルとしてエクスポートします

# #thinkphp5 について、および swoole が SMTP を介して非同期大量メール送信を実装する方法の詳細な説明


以上がPHP を使用して SWOOLE 拡張機能を有効にして MySQL データを定期的に同期する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート