1 <?php 2 3 class MemcacheController extends ControllerBase 4 { 5 public function indexAction() 6 { 7 session_start(); 8 $sessid = session_id(); 9 10 $server = array( 11 array('localhost',11200), 12 array('localhost',11201), 13 array('localhost',11202), 14 ); 15 $memCache = new Memcached('conn_pool'); 16 $curt_server = $this->connectMemcache($sessid,$memCache,$server); 17 echo "<br><br>目前鏈接的服務器:".json_encode($curt_server); 18 if(!empty($curt_server)){ 19 //設置60秒過時 20 $issetm = $memCache->set("user",$sessid,3600); 21 if($issetm) 22 { 23 echo "<br>設置memcached user成功!"; 24 } 25 } 26 } 27 public function getAction(){ 28 session_start(); 29 $sessid = session_id(); 30 $server = array( 31 array('localhost',11200), 32 array('localhost',11201), 33 array('localhost',11202), 34 ); 35 $memCache = new Memcached('conn_pool'); 36 $curt_server = $this->connectMemcache($sessid,$memCache,$server); 37 echo "<br><br>目前鏈接的服務器:".json_encode($curt_server); 38 $user_sid = $memCache->get("user"); 39 echo "sessionid=【{$sessid}】 獲取memcached數據:".$user_sid; 40 echo "<br>"; 41 //根據當前sessid 和 取出的 user的數據比較;不相同從新登陸 42 if($sessid != $user_sid){ 43 echo "////////從新登陸///////"; 44 $issetm = $memCache->set("user",$sessid,3600); 45 if($issetm) 46 { 47 echo "<br>設置sessionid memcached user成功!"; 48 } 49 } 50 } 51 private function connectMemcache( $sessid , $memCache , $server= array()){ 52 $server_num = count($server); 53 54 //獲取[memcached]服務器 55 $laststr = substr($sessid, -1); 56 $curr_idx = $this->bcd2char(strtolower($laststr)) % $server_num; 57 $host = $server[$curr_idx][0]; 58 $port = $server[$curr_idx][1]; 59 $serv = $host . ':' . $port; //預期鏈接的臺服務器[對應: $sessid] 60 echo "<br><br><br>------------------開始鏈接第【{$curr_idx}】臺server主機={$host} 端口={$port} 預期鏈接的地址:{$serv}----------------<br/>"; 61 $serv_arr = $memCache->getServerList(); 62 $list_cnt = count($serv_arr); 63 echo "當前活動的Memcached 總數:{$list_cnt}個 活動的 服務IP是:".json_encode($serv_arr)."<br>"; 64 if($list_cnt>0){ 65 //若是存在;判斷狀態 66 $stat_arr = $memCache->getStats(); 67 //獲取獲取服務器池中全部活動的服務器 68 $stat_ver = $memCache->getVersion(); 69 if($stat_arr){ 70 foreach ($stat_arr as $keyhost => $stat){ 71 if ($stat['pid'] > 0) { //若是存在活動的;判斷服務器的進程(pid >0)時, 表示該服務器正常! 72 if ($keyhost == $serv) { 73 //若是訪問ip與預期的ip相同返回當前ip 74 echo "已經找到該活動進程ID={$stat['pid']}服務器 版本:".json_encode($stat_ver)."<br>"; 75 return $server[$curr_idx]; 76 } 77 } 78 } 79 } 80 } 81 //若是爲匹配ip;則清除服務器列表中的全部服務器;從新添加 82 $resetmem = $memCache->resetServerList(); 83 if($resetmem){ 84 echo "+++++++++++++++清除服務器列表中的全部服務器;開始從新添加服務器列表Success.+++++++++++++++ <br/>"; 85 }else{ 86 echo "+++++++++++++++清除服務器列表中的全部服務器Faild+++++++++++++++.<br/>"; 87 } 88 //從新鏈接 89 if ($memCache->addServer($host, $port)) { /* 短鏈接模式 */ 90 echo "從新添加服務器第【{$curr_idx}】臺server主機={$host} 端口={$port}<br/>"; 91 //若是存在;判斷狀態 92 $stat_arr = $memCache->getStats(); 93 //獲取獲取服務器池中全部服務器的版本信息 94 $stat_ver = $memCache->getVersion(); 95 if($stat_arr){ 96 echo "<b><font color=green>從新添加服務器成功;服務器版本:".json_encode($stat_ver)."</font></b><br>"; 97 return $server[$curr_idx]; 98 }else{ 99 echo "=================================添加狀態失敗 server主機={$host} 端口={$port}=================================<br>"; 100 //刪去失敗的[memcached]配置 101 $temp = $server[$curr_idx]; 102 unset($server[$curr_idx]); 103 $resetmem = $memCache->resetServerList();//還原服務器列表 104 if(count($server)>0 && $resetmem){ 105 sort($server); 106 echo "<b><font color=red>【開始刪除】鏈接失敗的服務器:{$temp[0]}:{$temp[1]} *****重試其餘的服務列表:".json_encode($server)."</font><b><br>"; 107 return $this->connectMemcache($sessid , $memCache , $server); 108 }else{ 109 echo "No valid memcached servers!"; 110 return false; 111 } 112 } 113 } 114 } 115 /* 116 * BCD到字符碼 117 * @param $char 字符碼到BCD 118 * @return 字符碼 119 */ 120 private function bcd2char($char) 121 { 122 $bcd = ord($char); 123 if ($bcd >= 97 && $bcd <= 102) { 124 //'a'..'f' 125 return $bcd - 87; 126 } else { 127 //'0'..'9' 128 return $bcd - 48; 129 } 130 } 131 132 }
目標主機:localhost:11200 | localhost:11201 | localhost:11202php
根據user客戶端的sessionid 來定位使用哪臺服務器;若是其中一臺掛掉;則;循環添加其餘的memcache;直到添加成功返回;鏈接的當前主機IP;json
運行結果:服務器