Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4165996
  • 博文数量: 291
  • 博客积分: 8003
  • 博客等级: 大校
  • 技术积分: 4275
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-30 18:28
文章分类

全部博文(291)

文章存档

2017年(1)

2013年(47)

2012年(115)

2011年(121)

2010年(7)

分类: 系统运维

2012-06-23 22:17:02

    当我们需要清除squid的某个URL,我们需要对squid发出purge请求,但是一次只能发出一个请求清除一个URL。
    当我们修改了某个模版或者页头和页尾时,会影响到某个目录下的很多个页面或者全站所有页面,需要清除某个域名目录下的所有时,
     1)比较笨的方法是列出所有的URL进行一个个清除,这种方法在URL数目太多时,提取URL是个难题
     2)更好的是停止squid把cache目录清空,然后重新建立索引目录,这种方法需要停止服务
     3)自然过期,但是这种时间太长,况且修改模版不会引起last-modified的变化
    我对这三种办法都感觉不满意,于是我研究了squid的cache文件格式见《从squid cache文件中提取url》,我写了一个程序实现了
     1)提交多个url,可以一块清除对应的缓存
     2)提交多个目录,可以把以对应目录为前缀的所有URL删除
     3)当提交域名时,表示全站清空。

代码如下(下面的代码显示有点错乱,大家可以到文库里查找yifangyou上传的文档,刚才才上传的没有审核通过因此不便提供下载链接):

点击(此处)折叠或打开

  1. <?php
  2. /*
  3.  * 作者:yifangyou
  4.    日期:2012-06-19 14:00:00
  5.    功能:按照多个目录或者多个URL的方式,清除squid的cache
  6.  */
  7.   //代理服务器的ip
  8.   $proxyIp="127.0.0.1";
  9.   //代理服务器端口
  10.     $proxyPort=83;
  11.     //代理服务器的缓存目录
  12.     $cacheDir="D:/squid_var/cache";
  13.     $proxySites=array(
  14.      //用户访问的域名 => 被代理的实际网站的域名,若是都是80的话就是一样即可
  15.         ""=>":83"
  16.     );
  17. $output="";    
  18. $result=array();
  19. $filedirs = array();
  20. //提交多个url的处理过程
  21. if($_POST["urls"]){
  22.     //访问的域名
  23.     $accessSite=$_POST["accessSite"];
  24.     //被代理的网站
  25.     $proxySite=$proxySites[$accessSite];
  26.     $output.="
    执行结果
    \n
    \n";
  27.     $urls=explode ("\n",$_POST["urls"]);
  28.     foreach($urls as $url2){
  29.         $url=trim($url2);
  30.         $output.="------------------------$url start-----------------------------\n";
  31.         $pos = strpos($url, $accessSite);
  32.         if ($pos !== false && $pos==0) {
  33.             $url=str_replace($accessSite, $proxySite,$url);
  34.             if(purge($proxyIp,$proxyPort,$url)==0){
  35.                 $result[$url2]=0;
  36.             }else{
  37.                 $result[$url2]=1;
  38.             }
  39.         }else{
  40.             $output.="skip $url\n";
  41.             $result[$url2]=-1;
  42.         }
  43.         $output.="------------------------$url end -----------------------------\n";
  44.     }
  45.     $output.="\n";
  46. }
  47. //提交多个目录的处理过程
  48. if($_POST["dirs"]){
  49.     //访问的域名
  50.   $accessSite=$_POST["accessSite"];
  51.   //被代理的网站
  52.   $proxySite=$proxySites[$accessSite];
  53.     //解析出多个要清除的URL
  54.     $clearUrls=explode ("\n",$_POST["dirs"]);
  55.     //替换为被代理的网站
  56.     if($$proxySite){
  57.         foreach($ds as $d){
  58.             $d=str_replace($accessSite, $proxySite,$d);
  59.             $clearUrls[]=$d;
  60.         }
  61.     }
  62.     //递归扫描cache目录下所有的cache文件路径
  63.     scan_dir($cacheDir);
  64.     $cacheurls = array();
  65.     foreach($filedirs as $filename){
  66.         if(!is_file($filename)){
  67.             continue;
  68.         }
  69.         //获取各个cache文件中的URL
  70.         $cacheUrl=getUrlFromCacheFile($filename);

  71.         foreach($clearUrls as $clearUrl){
  72.         
  73.          $clearUrl=str_replace($accessSite, $proxySite,$clearUrl);
  74.             $pos=strpos($cacheUrl,$clearUrl);
  75.             // echo "$cacheUrl,$clearUrl,$pos
    ";

  76.             //比较和
  77.             if($pos===0){
  78.                  //获得要清除的真实URL
  79.                     $cacheurls[]=$cacheUrl;
  80.             }
  81.         }
  82.     }
  83.     //获得要清除的Url后,逐个清除
  84.     if(count($cacheurls) > 0){
  85.         $accessSite=$_POST["accessSite"];
  86.         $proxySite=$proxySites[$accessSite];
  87.         $output.="
    执行结果
    \n
    \n";
  88.         foreach($cacheurls as $url2){

  89.             $url=trim($url2);
  90.             $output.="------------------------$url start-----------------------------\n";
  91.             $pos = strpos($url, $accessSite);
  92.             //清除URL
  93.             if(purge($proxyIp,$proxyPort,$url)==0){
  94.                     $result[$url2]=0;
  95.             }else{
  96.                     $result[$url2]=1;
  97.             }
  98.             $output.="------------------------$url end -----------------------------\n";
  99.         }
  100.         $output.="\n";
  101.     }else{
  102.         foreach($clearUrls as $u){
  103.             $result[$u]=-1;
  104.         }
  105.     }
  106. }
  107. ?>

  108. <!DOCTYPE html>
  109. <html xmlns="">
  110. <head>
  111. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  112. <title>刷新squid</title>
  113. <body>
  114. <?php
  115.     if($result){
  116.         echo "\n";
  117.         foreach($result as $url=>$isOk){
  118.             switch($isOk){
  119.                 case 0://成功
  120.                 $r="成功";
  121.                 break;
  122.                 case 1://成功
  123.                 $r="失败";
  124.                 break;
  125.                 case -1://跳过
  126.                 $r="跳过";
  127.                 break;
  128.             }
  129.             if($$proxySite){
  130.                 $url=str_replace($proxySite, $accessSite, $url);
  131.             }
  132.             echo "
  133. \n";
  134.         }
  135.         echo "
  136. URL结果
    $url$r
    \n"
    ;
  137.     }
  138. ?>

  139. <form action="" method="post">
  140. <table >
  141. <tr><td>选择站点:</td></tr>
  142. <tr><td>
  143. <select name="accessSite" >
  144.     <?php
  145.         foreach($proxySites as $accessSite=>$proxySite){
  146.             echo "\n";
  147.         }
  148.     ?>
  149. </select>
  150. </td></tr>
  151. <tr><td>输入一组URL(一个一行)</td></tr>
  152. <tr><td><textarea name="urls" style="width:1000px;height:200px;"></textarea></td></tr>
  153. <tr><td>刷新目录(一个一行)</td></tr>
  154. <tr><td><textarea name="dirs" style="width:1000px;height:200px;"></textarea></td></tr>
  155. <tr><td><input type="submit" value="提交" /></td></tr>
  156. </table>
  157. </form>
  158. <?php
  159.     echo $output;
  160. ?>
  161. </body></html>
  162. <?php
  163. //清除某个URL的cache文件
  164. function purge($proxyIp,$proxyPort,$url)
  165. {
  166.     global $output;
  167.     $host = parse_url($url);
  168.     $host = $host['host'];
  169.     if (empty($proxyIp)) {
  170.         $proxyIp = gethostbyname($host);
  171.     }
  172.     if (empty($proxyPort)) {
  173.         $proxyPort = "80";
  174.     }
  175.     $output.="正在从服务器".$proxyIp."更新".$url."\n";
  176.     $errstr = '';
  177.     $errno = '';
  178.     $fp = fsockopen ($proxyIp, $proxyPort, $errno, $errstr, 2);
  179.     if (!$fp)
  180.     {
  181.          $output.="连接失败!";
  182.          return -1;
  183.     }
  184.     else
  185.     {
  186.         $out = "PURGE ".$url." HTTP/1.1\r\n";
  187.         $out .= "Host:".$host."\r\n";
  188.         $out .= "Connection: close\r\n\r\n";
  189.         $output.="***********request start**************\n";
  190.         $output.=$out;
  191.         $output.="***********request end **************\n";
  192.         fputs ($fp, $out);
  193.         $output.="***********response start**************\n";
  194.         //是否更新成功
  195.         $isOk=false;
  196.         while($out = fgets($fp , 4096)){
  197.             if($out=="HTTP/1.0 200 OK\r\n"){
  198.                 //更新成功
  199.                 $isOk=true;
  200.             }
  201.             $output.=$out;
  202.             if($out=="\r\n"){
  203.                 break;
  204.             }
  205.         }
  206.         fclose ($fp);
  207.         $output.="***********response end **************\n";        
  208.         flush();
  209.         if($isOk){
  210.             return 0;
  211.         }else{
  212.             return 1;
  213.         }
  214.     }
  215. }

  216. //递归扫描cache目录下所有文件路径
  217. function scan_dir($dir) {
  218.         global $filedirs;
  219.         if (!is_dir($dir)) return false;
  220.         if ($dh = opendir($dir)) {
  221.             while (($file = readdir($dh)) !== false) {
  222.                 if ($file[0] == '.') continue;
  223.                 if($file=='swap.state')continue;
  224.                 $fullpath = "$dir/$file";
  225.                 $filedirs[] = $fullpath;
  226.                 if (is_dir($fullpath))
  227.                     scan_dir($fullpath);
  228.             }
  229.             closedir($dh);
  230.         }
  231.         return $filedirs;
  232. }

  233. //从cache文件中提取真实的URL
  234. function getUrlFromCacheFile($filename){
  235.         //cache文件头长度
  236.         $headerLen=0x40;
  237.         $handle = fopen($filename, "rb");
  238.         if(!$handle){
  239.             return -1;
  240.         }
  241.         //读取文件的前1k字节
  242.         $contents = fread($handle, 1024);
  243.         fclose($handle);
  244.         if(strlen($contents)<=$headerLen){
  245.             return -2;
  246.         }
  247.         //截掉文件头
  248.         $contents=substr($contents,$headerLen);
  249.         
  250.         //cache文件的分隔符为\0
  251.         $pos=strpos($contents, chr(0));
  252.         if($pos===FALSE){
  253.             return -3;
  254.         }
  255.         //获取分隔符前的字符串
  256.         $contents=substr($contents,0,$pos);
  257.         return $contents;
  258. }
  259. ?>


测试过程:

阅读(4329) | 评论(3) | 转发(3) |
给主人留下些什么吧!~~

guigui342012-06-25 13:23:52

不错

跑马溜溜2012-06-24 10:37:25

有点和chinacache的界面类似,很好,很强大,收藏了

xieyunge2012-06-23 23:06:00

博客样式乱了,不过写得很详细啊太棒了