Gearman 实现多数据库数据同步
测试环境:windows(mysql)+ 虚拟机(ubuntu + mysql)+ PHP
1:gearman 的官方文档可以了解gearman,在ubuntu中安装gearman :
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install gcc autoconf bison flex libtool make libboost-all-dev libcurl4-openssl-dev curl libevent-dev memcached uuid-dev libsqlite3-dev libmysqlclient-dev
2:下载gearman
wget https://launchpad.net/gearmand/1.2/1.1.5/+download/gearmand-1.1.5.tar.gz
3:解压安装:
tar xvzf gearmand-1.1.5.tar.gz
cd gearmand-1.1.5
./configure
make
make install
如有错误根据错误提示: sudo apt-get install ....等;
4: 通过pecl 安装gearman (默认你的ubuntu已经安装了php):
sudo apt-get install php-pear
sudo pecl install gearman
sudo gedit /etc/php5/cli/php.ini
在文件末尾添加 extension="gearman.so";
5: 终端输入: php --info | grep "gearman support" 出现gearman support => enabled 则表示成功!
6:启动gearmand:sudo gearmand -d &
注意:这时可能会报错:gearmand: Could not open log file "/var/log/gearmand.log", from "/home/cj", switching to stderr. (Permission denied)
解决方法:
mkdir -p /usr/local/var/log/
cd /usr/local/var/log/
touch gearmand.log
再次启动:gearmand,通过 ps -ef | grep gearmand 查看gearman的进程。
7:PHP测试(多服务器数据库数据同步)
(1)环境:主机windows中安装mysql,设置数据库登录名:cw 和密码 : cw123;
虚拟机ubuntu安装mysql,设置数据库登陆名:cu 和密码 :cu123。
在两个数据库中分别建一张表:fb_table(表名)。
(2)服务端:serverCJ.php:(内容)
1 2 3 <?php 4 5 $worker = new GearmanWorker(); 6 $worker->addServer("127.0.0.1",4730); 7 $worker->addServer("192.168.238.2",4730); 8 9 $worker->addFunction('func1', function(GearmanJob $job){ 10 11 $str = $job->workload(); 12 $datas = json_decode($str,true); 13 14 $key = $datas["key"]; 15 $lang= $datas["lang"]; 16 $texts = $datas["text"]; 17 $kid = $datas["aid"]; 18 19 $con = mysql_connect("192.168.238.2","cw","cw123"); 20 if (!$con) 21 { 22 die('Could not connect: ' . mysql_error()); 23 } 24 $sqls = "select count(1) from fb_table where albumkey='".$key."'"; 25 $count = mysql_query($sqls,$mycon); 26 if($count>0){ 27 $strSql="update fb_table set albumkey='$key',langcode='$lang',texts='$texts',albumid='$kid'"; 28 } 29 else{ 30 $strSql="insert into fb_table(albumkey,langcode,texts,albumid) values('$key','$lang','$texts','$kid')"; 31 } 32 33 $result=mysql_query($strSql,$mycon); 34 sleep(3); 35 return 'The user requested ('.$result.') is func1'; 36 }); 37 38 $worker->addFunction('func2', function(GearmanJob $job){ 39 $str = $job->workload(); 40 $datas = json_decode($str,true); 41 42 $key = $datas["key"]; 43 $lang= $datas["lang"]; 44 $texts = $datas["text"]; 45 $kid = $datas["aid"]; 46 47 $con = mysql_connect("127.0.0.1","cu","cu123"); 48 if (!$con) 49 { 50 die('Could not connect: ' . mysql_error()); 51 } 52 $sqls = "select count(1) from fb_table where albumkey='".$key."'"; 53 $count = mysql_query($sqls,$mycon); 54 if($count>0){ 55 $strSql="update fb_table set albumkey='$key',langcode='$lang',texts='$texts',albumid='$kid'"; 56 } 57 else{ 58 $strSql="insert into fb_table(albumkey,langcode,texts,albumid) values('$key','$lang','$texts','$kid')"; 59 } 60 61 $result=mysql_query($strSql,$mycon); 62 63 sleep(3); 64 return 'The user ('. $result .') is func2'; 65 }); 66 67 68 while ($worker->work()); 69 70
(3) 客户端:clientCJ.php:(内容)
1 <?php 2 3 $key =$_POST['key']; 4 $lang =$_POST['lang']; 5 $text=$_POST['textmsg']; 6 $aid =$_POST['aid']; 7 8 $client = new GearmanClient(); 9 $client->addServer("127.0.0.1",4730); 10 11 $userInfo = $friends = null; 12 13 $client->setCompleteCallback(function(GearmanTask $task, $context) use (&$userInfo, &$friends) { 14 switch($context) { 15 case func1 16 $userInfo = $task->data(); 17 break; 18 case 'func2' 19 $friends = $task->data(); 20 break; 21 } 22 }); 23 24 $data=array("key"=>$key,"lang"=>$lang,"text"=>$text,"aid"=>$aid); 25 $datas=json_encode($data); 26 27 $client->addTask('func1', $datas, 'func1'); 28 $client->addTask('func2', $datas, 'func2'); 29 30 echo "Fetching... "; 31 $start = microtime(true); 32 $client->runTasks(); 33 $totaltime = number_format(microtime(true) - $start, 2); 34 35 echo "Got user info in: $totaltime seconds: "; 36 var_dump($userInfo, $friends);
(4)请求页面:submit.html
1 <form action="./clientCJ.php" method="post"> 2 <table> 3 <tr> 4 <td> 5 key:<input type="text" name="key" id="key" value="keys" /> 6 langcode:<input type="text" name="lang" id="lang" value="zh" /> 7 </td> 8 <td> 9 texts:<input type="text" name="texts" id="texts" value="textmsg" /> 10 albumid:<input type="text" name="aid" id="aid" value="12"/> 11 </td> 12 </tr> 13 </table> 14 <input type="button" value="提交" onclick="submins()" /> 15 </form>
注:在serverCJ中 $worker->addServer("192.168.238.2",4730); 的IP号为本机(windows的ip地址)即链接windows的数据库。
(5)运行:在终端输入 : php /**/serverCJ.php & (其中 **为serverCJ 的存放路径);运行服务端
在打开另一个终端,输入: php /**/clientCJ.php 运行客户端。
验证数据是否成功插入数据库:在ubuntu中进入数据库查询刚才新建的表 fb_table ,发现插入了一条数据,同样windows主机的数据库一样多了一条数据。!!
总结:实现了php运用gearman分别向两个服务器的数据库插入数据,实现数据同步。当然PHP同样能实现,但效率要慢得多。