批量清除nginx缓存的方法

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

nginx_cache文件格式

我写了一个程序能够实现

1.提交一批url进行清除对应的cache

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

3.查看某个目录下的缓存文件是否缓存上

4.可以添加多个站点

需要县安装ngx_cache_purge

代码如下

 

  
  
  
  
  1. <?php  
  2. /*  
  3.  * 作者:yifangyou  
  4.    日期:2012-07-21 14:43:00  
  5.    功能:按照多个目录或者多个URL的方式,清除nginx的cache,或者查看nginx cache 缓存  
  6.    要求:nginx + ngx_cache_purge  
  7.  */ 
  8.    //代理服务器的ip  
  9.   $proxyIp="127.0.0.1";  
  10.   //代理服务器端口  
  11.     $proxyPort=80;  
  12.     //代理服务器的缓存目录  
  13.     $cacheDir="/opt/proxy_cache_dir/";  
  14.     $proxySites=array(  
  15.     //用户访问的域名 => 被代理的实际网站的域名,若是都是80的话就是一样即可  
  16.      "http://www.test.com"=>"http://www.test.com" 
  17.     );  
  18. //输出文件  
  19. $output="";      
  20. $result=array();  
  21. $filedirs = array();  
  22. //只查看缓存文件,不清除  
  23. if($_POST["view"]){  
  24.          $accessSite=$_POST["accessSite"];  
  25.      $proxySite=$proxySites[$accessSite];  
  26.          $clearUrls=array();  
  27.          $clearUrls=explode ("\n",$_POST["dirs"]);  
  28.          if($$proxySite){  
  29.                  foreach($ds as $d){  
  30.                          $d=str_replace($accessSite$proxySite,$d);  
  31.                          $clearUrls[]=$d;  
  32.                  }  
  33.          }  
  34.          scan_dir($cacheDir);  
  35.          $cacheurls = array();  
  36.          foreach($filedirs as $filename){  
  37.                 if(!is_file($filename)){  
  38.                         continue;  
  39.                 }  
  40.                 $cacheUrl=getUrlFromCacheFile($filename);  
  41.                                 if(count($clearUrls)){  
  42.                                     $cacheurls[]=$cacheUrl;  
  43.                                     continue;  
  44.                                 }  
  45.                 foreach($clearUrls as $clearUrl){  
  46.                   $clearUrl=str_replace($accessSite$proxySite,$clearUrl);  
  47.                   $pos=strpos($cacheUrl,$clearUrl);  
  48.                   // echo "$cacheUrl,$clearUrl,$pos<br/>";  
  49.                   //比较http://www.b.com/a/b.jpg和http://www.b.com/a  
  50.                   if($pos===0){  
  51.                      $cacheurls[]=$cacheUrl;  
  52.                      break;  
  53.                    }  
  54.                 }  
  55.         }  
  56.  
  57. }else //清除一批URL  
  58. if($_POST["urls"]){  
  59.     $accessSite=$_POST["accessSite"];  
  60.     $proxySite=$proxySites[$accessSite];  
  61.     $output.="<div style='font-size:16px;font-weight:bold'>执行结果  
  62. \n\n";  
  63.     $urls=explode ("\n",$_POST["urls"]);  
  64.     foreach($urls as $url2){  
  65.         $url=trim($url2);  
  66.         $output.="------------------------$url start-----------------------------\n";  
  67.         $pos = strpos($url$accessSite);  
  68.         if ($pos !== false && $pos==0) {  
  69.             $url=str_replace($accessSite$proxySite,$url);  
  70.             if(purge($proxyIp,$proxyPort,$url)==0){  
  71.                 $result[$url2]=0;  
  72.             }else{  
  73.                 $result[$url2]=1;  
  74.             }  
  75.         }else{  
  76.             $output.="skip $url\n";  
  77.             $result[$url2]=-1;  
  78.         }  
  79.         $output.="------------------------$url end -----------------------------\n";  
  80.     }  
  81.     $output.="\n";  
  82. }else//清除某个目录下的所有文件  
  83. if($_POST["dirs"]){  
  84.     $accessSite=$_POST["accessSite"];  
  85.     $proxySite=$proxySites[$accessSite];  
  86.     $clearUrls=array();  
  87.     $clearUrls=explode ("\n",$_POST["dirs"]);  
  88.     if($$proxySite){  
  89.         foreach($ds as $d){  
  90.             $d=str_replace($accessSite$proxySite,$d);  
  91.             $clearUrls[]=$d;  
  92.         }  
  93.     }  
  94.     scan_dir($cacheDir);  
  95.     $cacheurls = array();  
  96.     foreach($filedirs as $filename){  
  97.         if(!is_file($filename)){  
  98.             continue;  
  99.         }  
  100.         $cacheUrl=getUrlFromCacheFile($filename);  
  101.  
  102.         foreach($clearUrls as $clearUrl){  
  103.          $clearUrl=str_replace($accessSite$proxySite,$clearUrl);  
  104.             $pos=strpos($cacheUrl,$clearUrl);  
  105.             // echo "$cacheUrl,$clearUrl,$pos<br/>";  
  106.             //比较http://www.b.com/a/b.jpg和http://www.b.com/a  
  107.             if($pos===0){  
  108.                     $cacheurls[]=$cacheUrl;  
  109.                     break;  
  110.             }  
  111.         }  
  112.     }  
  113.     if(count($cacheurls) > 0){  
  114.         $accessSite=$_POST["accessSite"];  
  115.         $proxySite=$proxySites[$accessSite];  
  116.         $output.="<div style='font-size:16px;font-weight:bold'>执行结果  
  117. \n\n";  
  118.         foreach($cacheurls as $url2){  
  119.  
  120.             $url=trim($url2);  
  121.             $output.="------------------------$url start-----------------------------\n";  
  122.             $pos = strpos($url$accessSite);  
  123.             if(purge($proxyIp,$proxyPort,$url)==0){  
  124.                     $result[$url2]=0;  
  125.             }else{  
  126.                     $result[$url2]=1;  
  127.             }  
  128.             $output.="------------------------$url end -----------------------------\n";  
  129.         }  
  130.         $output.="\n";  
  131.     }else{  
  132.         foreach($clearUrls as $u){  
  133.             $result[$u]=-1;  
  134.         }  
  135.     }  
  136. }  
  137. ?>  
  138.  
  139. <!DOCTYPE html>  
  140. <html xmlns="http://www.w3.org/1999/xhtml">  
  141. <head>  
  142. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  143. <title>刷新squid</title>  
  144. <body>  
  145. <?php  
  146.     if($result){  
  147.         echo "<table border='1'><tr><td>URL</td><td>结果</td></tr>\n";  
  148.         foreach($result as $url=>$isOk){  
  149.             switch($isOk){  
  150.                 case 0://成功  
  151.                 $r="<font style='color:#90EE90'>成功</font>";  
  152.                 break;  
  153.                 case 1://成功  
  154.                 $r="<font color='red'>失败</font>";  
  155.                 break;  
  156.                 case -1://跳过  
  157.                 $r="<font color='Yellow'>跳过</font>";  
  158.                 break;  
  159.             }  
  160.             if($$proxySite){  
  161.                 $url=str_replace($proxySite$accessSite$url);  
  162.             }  
  163.             echo "<tr><td>$url</td><td>$r</td></tr>\n";  
  164.         }  
  165.         echo "</table>\n";  
  166.     }  
  167. ?>  
  168.  
  169. <form action="" method="post">  
  170. <table >  
  171. <tr><td>选择站点:</td></tr>  
  172. <tr><td>  
  173. <select name="accessSite" id="accessSite">  
  174.     <?php  
  175.         foreach($proxySites as $accessSite => $proxySite){  
  176.         $isSelected=$_POST["accessSite"]==$accessSite?"selected":"";  
  177.             echo "<option value='$accessSite' $isSelected>$accessSite</option>\n";  
  178.         }  
  179.     ?>  
  180. </select>  
  181. <script>  
  182.     function view(){  
  183.         location="?accessSite="+document.getElementById("accessSite").value+"&view=1";      
  184.     }      
  185. </script>  
  186. <input type="checkbox" name="view" value="1" <?php echo $_POST["view"]?"checked":"";?>/><label for="view">只查看</label>  
  187. </td></tr>  
  188. <tr><td>输入一组URL(一个一行):</td></tr>  
  189. <tr><td><textarea name="urls" style="width:1000px;height:200px;"><?php if($_POST["view"])foreach($cacheurls as $cacheurl){echo "$cacheurl\n";}?></textarea></td></tr>  
  190. <tr><td>刷新目录(一个一行):</td></tr>  
  191. <tr><td><textarea name="dirs" style="width:1000px;height:200px;"></textarea></td></tr>  
  192. <tr><td><input type="submit" value="提交" /></td></tr>  
  193. </table>  
  194. </form>  
  195. <?php  
  196.     echo $output;  
  197. ?>  
  198. </body></html>  
  199. <?php  
  200. //清除某个url  
  201. function purge($proxyIp,$proxyPort,$url)  
  202. {  
  203.     global $output;  
  204.     $host = parse_url($url);  
  205.     $host = $host['host'];  
  206.     $purge_url=str_replace("http://".$host,"/purge",$url);  
  207.     if (emptyempty($proxyIp)) {  
  208.         $proxyIp = gethostbyname($host);  
  209.     }  
  210.     if (emptyempty($proxyPort)) {  
  211.         $proxyPort = "80";  
  212.     }  
  213.     $output.="正在从服务器".$proxyIp."更新".$url."\n";  
  214.     $errstr = '';  
  215.     $errno = '';  
  216.     $fp = fsockopen ($proxyIp$proxyPort$errno$errstr, 2);  
  217.     if (!$fp)  
  218.     {  
  219.          $output.="连接失败!";  
  220.          return -1;  
  221.     }  
  222.     else 
  223.     {  
  224.         $out = "GET ".$purge_url." HTTP/1.1\r\n";  
  225.         $out .= "Host:".$host."\r\n";  
  226.         $out .= "Connection: close\r\n\r\n";  
  227.         $output.="***********request start**************\n";  
  228.         $output.=$out;  
  229.         $output.="***********request end **************\n";  
  230.         fputs ($fp$out);  
  231.         $output.="***********response start**************\n";  
  232.         //是否更新成功  
  233.         $isOk=false;  
  234.         while($out = fgets($fp , 4096)){  
  235.             if(strpos($out,"200 OK\r\n")!==FALSE){  
  236.                 //更新成功  
  237.                 $isOk=true;  
  238.             }  
  239.             $output.=$out;  
  240.             if($out=="\r\n"){  
  241.                 break;  
  242.             }  
  243.         }  
  244.         fclose ($fp);  
  245.         $output.="***********response end **************\n";          
  246.         flush();  
  247.         if($isOk){  
  248.             return 0;  
  249.         }else{  
  250.             return 1;  
  251.         }  
  252.     }  
  253. }  
  254.  
  255. //递归扫描cache目录下所有文件路径  
  256. function scan_dir($dir) {  
  257.         global $filedirs;  
  258.         if (!is_dir($dir)) return false;  
  259.         if ($dh = opendir($dir)) {  
  260.             while (($file = readdir($dh)) !== false) {  
  261.                 if ($file[0] == '.'continue;  
  262.                 if($file=='swap.state')continue;  
  263.                 $fullpath = "$dir/$file";  
  264.                 $filedirs[] = $fullpath;  
  265.                 if (is_dir($fullpath))   
  266.                     scan_dir($fullpath);   
  267.             }  
  268.             closedir($dh);  
  269.         }  
  270.         return $filedirs;  
  271. }  
  272. //从cache文件中提取真实的URL  
  273. function getUrlFromCacheFile($filename){  
  274.         //cache文件头长度  
  275.         $headerLen=0x1E;  
  276.         $handle = fopen($filename"rb");  
  277.         if(!$handle){  
  278.             return -1;   
  279.         }  
  280.         //读取文件的前1k字节  
  281.         $contents = fread($handle, 1024);  
  282.         fclose($handle);  
  283.         if(strlen($contents)<=$headerLen){  
  284.             return -2;   
  285.         }  
  286.         //截掉文件头  
  287.         $contents=substr($contents,$headerLen);  
  288.           
  289.         //cache文件的分隔符为\A  
  290.         $pos=strpos($contentschr(0x0A));  
  291.         if($pos===FALSE){  
  292.             return -3;   
  293.         }  
  294.         //获取分隔符前的字符串  
  295.         $contents="http://".substr($contents,0,$pos);  
  296.         return $contents;  
  297. }  
  298. ?> 

测试

nginx缓存2

你可能感兴趣的:(nginx,cache,clear,清除,ngx_cache_purge)