標籤:
從資料庫中直接讀取資料,雖然時效性很強,但是對資料庫造成很大壓力,尤其是在高訪問量的情況下。這時候可以通過緩衝,來有效緩解了這一壓力,雖然時效性有些不足,但是伺服器的抗壓能力卻達到了很大的提高。
讀取緩衝方式的中心思想:
當請求進來時,先查看是否有緩衝,如果有並且緩衝還在有效時間內,不再查詢資料庫,直接返回緩衝即可;如果沒有或者已經過了有效時間,查詢資料庫,返回資料,同時產生一份新的緩衝,供以後使用。
代碼案例,還是在前幾天的代碼基礎上進行改造完善。
File靜態緩衝類 (原來的代碼請參考 http://my.oschina.net/woshixiaomayi/blog/517876)
做了一些修改,將原來cacheData()方法中的第三個參數,由path修改成了cacheTime,用來記錄緩衝的有效時間。在方法中增加了,寫入緩衝時間的邏輯,和判斷快取檔案是否到期的邏輯,如下:
<?php/********************************** 修改File類,cacheData方法中加入了緩衝時間參數* 學php的小螞蟻* 原創部落格 http://my.oschina.net/woshixiaomayi/blog****************************/ class File{ //快取檔案的路徑 private $_dir; //快取檔案的預設路徑 const EXT=‘.txt‘; //構造方法組建目錄 function __construct(){ $this->_dir = dirname(__FILE__).‘/files/‘; if(!is_dir($this->_dir)){ mkdir($this->_dir,0777); } } /************************* * * 快取檔案的產生,修改,刪除,第三個參數改成了緩衝時間 * $value有值,寫入。無值,讀出。為null,刪除 * @param string $key 檔案名稱 * @param mixed $value 緩衝的資料 * @param int $cacheTime 快取檔案的有效時間 * return mixed 傳回值為布爾值,字串,整型 * *******************/ public function cacheData($key,$value=‘‘,$cacheTime=0){ //快取檔案的全路徑 $filename = $this->_dir.$key.self::EXT; //如果value為null,這刪除這個靜態緩衝 if(is_null($value)){ return @unlink($filename); } //如果$value不等於空,說明是寫入操作 if($value != ‘‘){ //判斷提交的path是否存在 $dir = dirname($filename); if(!is_dir($dir)){ mkdir($dir,0777); } /* 在進行寫入操作的時候,附帶上緩衝有效時間 有效時間為11位的整形,不足11位在前端用0補足 這樣做方便截取 */$cacheTime=sprintf(‘%011d‘,$cacheTime); //將緩衝有效時間拼接資料json,儲存到檔案 return file_put_contents($filename,$cacheTime.json_encode($value)); }elseif($value == ‘‘){ //說明是讀取操作 if(is_file($filename)){ /* 因為加入了緩衝時間,需要將它們拆分開來,進行判斷, 緩衝是否到期,如果沒有到期,返回資料,如果到期了, 刪除源檔案,返回false。 */$content=file_get_contents($filename); //拿到本檔案的緩衝有限時間$time=(int)substr($content,0,11); /* 進行判斷緩衝是否可用 1.判斷到期時間是不是永久緩衝(為0則是永久緩衝) 2.緩衝時間加上檔案修改時間是否小於現在時間,如果小於 則已經到期 */if($time != 0 && ($time + filemtime($filename) < time())){//快取檔案不可用,刪除該檔案,返回falseunlink($filename);return false;}//快取資料可用,拿出資料,直接返回$value=substr($content,11); return json_decode($value,true); }else{ return false; } } }}?>
邏輯代碼中,需要作出判斷,是否存在快取檔案。有並且沒有到期,則使用快取檔案,不再讀取資料庫,沒有或者已經到期,則走查詢資料庫的步驟,同時產生快取檔案。代碼中的echo 123,是測試使用,注釋已經做出了說明。
<?php/*************************************讀取資料庫的方式開發首頁介面*學php的小螞蟻*部落格 http://my.oschina.net/woshixiaomayi/blog*************************************///載入前天寫的db類//代碼內容請參考 http://my.oschina.net/woshixiaomayi/blog/518295require_once(‘./db.php‘);//載入之前寫好的介面響應類//代碼內容請參考 http://my.oschina.net/woshixiaomayi/blog/517384require_once(‘./response.php‘);//載入剛剛改造好的檔案靜態緩衝類require_once(‘./file.php‘);//接收分頁資料 page 為當前第幾頁 pagesize 一頁多少資料$page=isset($_GET[‘page‘])?$_GET[‘page‘]:1;$pagesize=isset($_GET[‘pagesize‘])?$_GET[‘pagesize‘]:5;//檢測這兩個數值是否為數字if(!is_numeric($page) or !is_numeric($pagesize)){//不是數字,發送錯誤提示/*這裡之所以使用了一個return是加強了程式的可讀性,因為對程式不熟悉的程式員,不知道在show方法中有exit,加上一個return,其他人就會知道執行到這一步之後,程式就會停止,後面的程式就不會執行了。方便了其他人,大家好才是真的好\(^o^)/YES!*/return Response::show(400,‘參數不合法‘);}//設定分頁所需要的位移量$offset=($page-1)*$pagesize;//編寫sql語句$sql="select * from ecm_member limit ".$offset.",".$pagesize;//執行個體化檔案快取類,查看是否存在有效時間內的快取檔案$file=new File();if(!$index_data=$file->cacheData(‘list‘.$page.‘_‘.$pagesize)){/*此處為調試,在第一次訪問的時候,echo 的123可以出現,之後訪問,由於已經產生緩衝,則不再走這一步,所以123不會出現。直到有效時間過去,才會再次出現*/echo 123;//如果串連資料庫的時候出錯,擷取資訊,並將自訂的資訊返回//以免將錯誤直接暴露給使用者try{$connect =Db::getInstance()->connect();}catch(Exception $e){//返回給APP的錯誤提示return Response::show(400,‘mysql not connect‘);}//資料庫連接成功,執行sql語句,擷取結果集$result=mysql_query($sql,$connect);$index_data=array();while($row=mysql_fetch_assoc($result)){$index_data[]=$row;}$file->cacheData(‘list‘.$page.‘_‘.$pagesize,$index_data,15);}if($index_data){//所需的結果資料拿到,返回資料return Response::show(200,‘內容擷取成功‘,$index_data);}else{//沒有拿到,返回錯誤提示return Response::show(400,‘首頁資料擷取失敗‘);}?>
讀取緩衝方式開發介面的思想基本上就是這樣了,很好理解,不過這裡用了一個最笨的方法,在本地儲存檔案的形式做了緩衝,其實可以使用一些更進階的服務,例如memcache、redis等進行緩衝,效率更高,有時間的話,使用這兩種服務再測試一下 ~(~ ̄▽ ̄)~ 加了個油。
小螞蟻學習APP介面開發(7)—— APP介面執行個體——讀取緩衝方式開發APP介面的代碼案例