批量清除nginx缓存的方法

简介:

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

bde6c90bbd40a2ae61d490fc23fb5705925d740a

我写了一个程序能够实现

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;  
}  
?> 

测试

2e11db0a65d0202e7628e80b520b2d4ca9d86ef6

相关文章
|
2月前
|
缓存 应用服务中间件 网络安全
Nginx中配置HTTP2协议的方法
Nginx中配置HTTP2协议的方法
148 7
|
5月前
|
缓存 应用服务中间件 nginx
成功解决 Nginx更新静态资源无效 ,Nginx静态资源更新不及时,Nginx清除缓存
这篇文章讨论了在使用Nginx进行动静分离时遇到的静态资源更新不及时的问题。问题描述了在服务器上更新静态资源后,访问页面时页面没有显示更新的情况。文章提供了解决这个问题的方法,即清除浏览器缓存,并提供了相关参考文章链接。此外,还展示了问题复现的步骤和正常情况的预期结果。
成功解决 Nginx更新静态资源无效 ,Nginx静态资源更新不及时,Nginx清除缓存
|
5月前
|
应用服务中间件 Linux 调度
干货!几个 Nginx 性能优化方法
干货!几个 Nginx 性能优化方法
164 0
|
3月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
101 15
Android 系统缓存扫描与清理方法分析
|
5月前
|
SQL 缓存 开发框架
分享一个 .NET EF6 应用二级缓存提高性能的方法
分享一个 .NET EF6 应用二级缓存提高性能的方法
|
2月前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
76 10
|
2月前
|
缓存 监控 NoSQL
Redis 缓存穿透的检测方法与分析
【10月更文挑战第23天】通过以上对 Redis 缓存穿透检测方法的深入探讨,我们对如何及时发现和处理这一问题有了更全面的认识。在实际应用中,我们需要综合运用多种检测手段,并结合业务场景和实际情况进行分析,以确保能够准确、及时地检测到缓存穿透现象,并采取有效的措施加以解决。同时,要不断优化和改进检测方法,提高检测的准确性和效率,为系统的稳定运行提供有力保障。
64 5
|
3月前
|
存储 缓存 监控
|
3月前
|
存储 缓存 负载均衡
Nginx代理缓存机制
【10月更文挑战第2天】
119 4
|
3月前
|
存储 缓存 NoSQL
Nginx缓存
Nginx缓存
34 2