當前位置: 首頁IT技術(shù) → 批量清除nginx緩存的方法

批量清除nginx緩存的方法

更多

我公司的一個客戶在國外訪問測試網(wǎng)站比較麻煩,因此我在一臺機器上安裝了一個nginx,并且使用nginx的proxy_cache模塊做緩存服務(wù)器,由于由于修改比較多,每次使用ngx_cache_purge清除cache只能清除幾個url,沒有很好的辦法去清除某個目錄的緩存。我研究了nginx的緩存文件格式,發(fā)現(xiàn)可以從中提取出url出來,如下圖所示,url是以"KEY:"開頭以0x0A結(jié)尾

我寫了一個程序能夠?qū)崿F(xiàn)

1.提交一批url進行清除對應(yīng)的cache

2.提交一批url目錄可以清除包含這些目錄的url,若是提交域名可以清除整站

3.查看某個目錄下的緩存文件是否緩存上

4.可以添加多個站點

需要縣安裝ngx_cache_purge

代碼如下

<?php  

/*  

* 作者:yifangyou  

日期:2012-07-21 14:43:00  

功能:按照多個目錄或者多個URL的方式,清除nginx的cache,或者查看nginx cache 緩存  

要求:nginx + ngx_cache_purge  

*/ 

//代理服務(wù)器的ip  

$proxyIp="127.0.0.1";  

//代理服務(wù)器端口  

$proxyPort=80;  

//代理服務(wù)器的緩存目錄  

$cacheDir="/opt/proxy_cache_dir/";  

$proxySites=array(  

//用戶訪問的域名 => 被代理的實際網(wǎng)站的域名,若是都是80的話就是一樣即可  

"http://www.test.com"=>"http://www.test.com" 

);  

//輸出文件  

$output="";      

$result=array();  

$filedirs = array();  

//只查看緩存文件,不清除  

if($_POST["view"]){  

$accessSite=$_POST["accessSite"];  

$proxySite=$proxySites[$accessSite];  

$clearUrls=array();  

$clearUrls=explode ("\n",$_POST["dirs"]);  

if($$proxySite){  

foreach($ds as $d){  

$d=str_replace($accessSite, $proxySite,$d);  

$clearUrls[]=$d;  

}  

}  

scan_dir($cacheDir);  

$cacheurls = array();  

foreach($filedirs as $filename){  

if(!is_file($filename)){  

continue;  

}  

$cacheUrl=getUrlFromCacheFile($filename);  

if(count($clearUrls)){  

$cacheurls[]=$cacheUrl;  

continue;  

}  

foreach($clearUrls as $clearUrl){  

$clearUrl=str_replace($accessSite, $proxySite,$clearUrl);  

$pos=strpos($cacheUrl,$clearUrl);  

// echo "$cacheUrl,$clearUrl,$pos<br/>";  

//比較http://www.b.com/a/b.jpg和http://www.b.com/a  

if($pos===0){  

$cacheurls[]=$cacheUrl;  

break;  

}  

}  

}  

}else //清除一批URL  

if($_POST["urls"]){  

$accessSite=$_POST["accessSite"];  

$proxySite=$proxySites[$accessSite];  

$output.="<div style='font-size:16px;font-weight:bold'>執(zhí)行結(jié)果  

\n\n";  

$urls=explode ("\n",$_POST["urls"]);  

foreach($urls as $url2){  

$url=trim($url2);  

$output.="------------------------$url start-----------------------------\n";  

$pos = strpos($url, $accessSite);  

if ($pos !== false && $pos==0) {  

$url=str_replace($accessSite, $proxySite,$url);  

if(purge($proxyIp,$proxyPort,$url)==0){  

$result[$url2]=0;  

}else{  

$result[$url2]=1;  

}  

}else{  

$output.="skip $url\n";  

$result[$url2]=-1;  

}  

$output.="------------------------$url end -----------------------------\n";  

}  

$output.="\n";  

}else//清除某個目錄下的所有文件  

if($_POST["dirs"]){  

$accessSite=$_POST["accessSite"];  

$proxySite=$proxySites[$accessSite];  

$clearUrls=array();  

$clearUrls=explode ("\n",$_POST["dirs"]);  

if($$proxySite){  

foreach($ds as $d){  

$d=str_replace($accessSite, $proxySite,$d);  

$clearUrls[]=$d;  

}  

}  

scan_dir($cacheDir);  

$cacheurls = array();  

foreach($filedirs as $filename){  

if(!is_file($filename)){  

continue;  

}  

$cacheUrl=getUrlFromCacheFile($filename);  

foreach($clearUrls as $clearUrl){  

$clearUrl=str_replace($accessSite, $proxySite,$clearUrl);  

$pos=strpos($cacheUrl,$clearUrl);  

// echo "$cacheUrl,$clearUrl,$pos<br/>";  

//比較http://www.b.com/a/b.jpg和http://www.b.com/a  

if($pos===0){  

$cacheurls[]=$cacheUrl;  

break;  

}  

}  

}  

if(count($cacheurls) > 0){  

$accessSite=$_POST["accessSite"];  

$proxySite=$proxySites[$accessSite];  

$output.="<div style='font-size:16px;font-weight:bold'>執(zhí)行結(jié)果  

\n\n";  

foreach($cacheurls as $url2){  

$url=trim($url2);  

$output.="------------------------$url start-----------------------------\n";  

$pos = strpos($url, $accessSite);  

if(purge($proxyIp,$proxyPort,$url)==0){  

$result[$url2]=0;  

}else{  

$result[$url2]=1;  

}  

$output.="------------------------$url end -----------------------------\n";  

}  

$output.="\n";  

}else{  

foreach($clearUrls as $u){  

$result[$u]=-1;  

}  

}  

}  

?>  

<!DOCTYPE html>  

<html xmlns="http://www.w3.org/1999/xhtml">  

<head>  

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  

<title>刷新squid</title>  

<body>  

<?php  

if($result){  

echo "<table border='1'><tr><td>URL</td><td>結(jié)果</td></tr>\n";  

foreach($result as $url=>$isOk){  

switch($isOk){  

case 0://成功  

$r="<font style='color:#90EE90'>成功</font>";  

break;  

case 1://成功  

$r="<font color='red'>失敗</font>";  

break;  

case -1://跳過  

$r="<font color='Yellow'>跳過</font>";  

break;  

}  

if($$proxySite){  

$url=str_replace($proxySite, $accessSite, $url);  

}  

echo "<tr><td>$url</td><td>$r</td></tr>\n";  

}  

echo "</table>\n";  

}  

?>  

<form action="" method="post">  

<table >  

<tr><td>選擇站點:</td></tr>  

<tr><td>  

<select name="accessSite" id="accessSite">  

<?php  

foreach($proxySites as $accessSite => $proxySite){  

$isSelected=$_POST["accessSite"]==$accessSite?"selected":"";  

echo "<option value='$accessSite' $isSelected>$accessSite</option>\n";  

}  

?>  

</select>  

<script>  

function view(){  

location="?accessSite="+document.getElementById("accessSite").value+"&view=1";      

}      

</script>  

<input type="checkbox" name="view" value="1" <?php echo $_POST["view"]?"checked":"";?>/><label for="view">只查看</label>  

</td></tr>  

<tr><td>輸入一組URL(一個一行):</td></tr>  

<tr><td><textarea name="urls" style="width:1000px;height:200px;"><?php if($_POST["view"])foreach($cacheurls as $cacheurl){echo "$cacheurl\n";}?></textarea></td></tr>  

<tr><td>刷新目錄(一個一行):</td></tr>  

<tr><td><textarea name="dirs" style="width:1000px;height:200px;"></textarea></td></tr>  

<tr><td><input type="submit" value="提交" /></td></tr>  

</table>  

</form>  

<?php  

echo $output;  

?>  

</body></html>  

<?php  

//清除某個url  

function purge($proxyIp,$proxyPort,$url)  

{  

global $output;  

$host = parse_url($url);  

$host = $host['host'];  

$purge_url=str_replace("http://".$host,"/purge",$url);  

if (emptyempty($proxyIp)) {  

$proxyIp = gethostbyname($host);  

}  

if (emptyempty($proxyPort)) {  

$proxyPort = "80";  

}  

$output.="正在從服務(wù)器".$proxyIp."更新".$url."\n";  

$errstr = '';  

$errno = '';  

$fp = fsockopen ($proxyIp, $proxyPort, $errno, $errstr, 2);  

if (!$fp)  

{  

$output.="連接失。";  

return -1;  

}  

else 

{  

$out = "GET ".$purge_url." HTTP/1.1\r\n";  

$out .= "Host:".$host."\r\n";  

$out .= "Connection: close\r\n\r\n";  

$output.="***********request start**************\n";  

$output.=$out;  

$output.="***********request end **************\n";  

fputs ($fp, $out);  

$output.="***********response start**************\n";  

//是否更新成功  

$isOk=false;  

while($out = fgets($fp , 4096)){  

if(strpos($out,"200 OK\r\n")!==FALSE){  

//更新成功  

$isOk=true;  

}  

$output.=$out;  

if($out=="\r\n"){  

break;  

}  

}  

fclose ($fp);  

$output.="***********response end **************\n";          

flush();  

if($isOk){  

return 0;  

}else{  

return 1;  

}  

}  

}  

//遞歸掃描cache目錄下所有文件路徑  

function scan_dir($dir) {  

global $filedirs;  

if (!is_dir($dir)) return false;  

if ($dh = opendir($dir)) {  

while (($file = readdir($dh)) !== false) {  

if ($file[0] == '.') continue;  

if($file=='swap.state')continue;  

$fullpath = "$dir/$file";  

$filedirs[] = $fullpath;  

if (is_dir($fullpath))   

scan_dir($fullpath);   

}  

closedir($dh);  

}  

return $filedirs;  

}  

//從cache文件中提取真實的URL  

function getUrlFromCacheFile($filename){  

//cache文件頭長度  

$headerLen=0x1E;  

$handle = fopen($filename, "rb");  

if(!$handle){  

return -1;   

}  

//讀取文件的前1k字節(jié)  

$contents = fread($handle, 1024);  

fclose($handle);  

if(strlen($contents)<=$headerLen){  

return -2;   

}  

//截掉文件頭  

$contents=substr($contents,$headerLen);  

//cache文件的分隔符為\A  

$pos=strpos($contents, chr(0x0A));  

if($pos===FALSE){  

return -3;   

}  

//獲取分隔符前的字符串  

$contents="http://".substr($contents,0,$pos);  

return $contents;  

}  

?> 

測試

熱門評論
最新評論
發(fā)表評論 查看所有評論(0)
昵稱:
表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
字數(shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)