当前位置: 首页IT技术 → 批量清除nginx缓存的方法

批量清除nginx缓存的方法

更多

我公司的一个客户在国外访问测试网站比较麻烦,因此我在一台机器上安装了一个nginx,并且使用nginx的proxy_cache模块做缓存服务器,由于由于修改比较多,每次使用ngx_cache_purge清除cache只能清除几个url,没有很好的办法去清除某个目录的缓存。我研究了nginx的缓存文件格式,发现可以从中提取出url出来,如下图所示,url是以"KEY:"开头以0x0A结尾

我写了一个程序能够实现

1.提交一批url进行清除对应的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  

*/ 

//代理服务器的ip  

$proxyIp="127.0.0.1";  

//代理服务器端口  

$proxyPort=80;  

//代理服务器的缓存目录  

$cacheDir="/opt/proxy_cache_dir/";  

$proxySites=array(  

//用户访问的域名 => 被代理的实际网站的域名,若是都是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'>执行结果  

\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'>执行结果  

\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>结果</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.="正在从服务器".$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字节  

$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;  

}  

?> 

测试

热门评论
最新评论
昵称:
表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
字数: 0/500 (您的评论需要经过审核才能显示)