利用http 404错误实现镜像同步功能

利用404错误做简易镜像同步功能,只针对html文件和图片等静态文件

实现方法:

后台服务器:绑定2个域名,www.xxx.com 和 jx.xxx.com 主域(cms域,可以放在双线服务器上)

1号服务器:www.xxx.com 镜像站点1(电信1)
2号服务器:www.xxx.com 镜像站点2(电信2)

3号服务器:www.xxx.com 镜像站点3(网通1)
4号服务器:www.xxx.com 镜像站点4(网通2)

……….more……………

域名www.xxx.com需要作智能DNS解析,使不同地区的人访问不同的镜像。

原理简介:
当你所在位置在网通1,访问www.xxx.com/a.html时,DNS智能解析被分配到3号服务器上,由于第一次访问时3号服务器上文件a.html并不存在,只是在后台服务器上有,3号服务器http此时将触发一个404页面不存在的错误,本文就是利用这个404来做镜像同步的,我们可以把404跳转页面指定到404.php,如apache添加配置:

ErrorDocument 404 /404.php

利用404.php来抓取cms后台服务器上(由于www.xxx.com做了智能解析,所以需绑定jx.xxx.com,通过抓取jx.xxx.com/a.html保存到本地)的内容并保存在本地,并输出抓取的数据确保即使是第一次访问也是成功的。以后访问a.html由于文件已经在本地了,所有直接返回本地数据(没有触发404错误)。

404.php代码:

<?php
/**
 +------------------------------------------------------------------------------
 * HXPHP Mirror Fetch For Pictures OR Html File
 +------------------------------------------------------------------------------
 *
@Author ieliwb<ieliwb@gmail.com>
 *
@Copyright (c) www.ieliwb.com
 +------------------------------------------------------------------------------
 */

 
//var_dump($_SERVER);
//exit();
 
header("Pargma:no-cache\r\n");
header("Cache-Control:no-cache\r\n");
 
$host = 'http://jx.xxx.com';        //主镜像域
$path = trim($_SERVER['REQUEST_URI']);        //抓取路径
 
$ext = GetExt($path);
 
//自动抓取远程静态文件本地化处理
if(in_array($ext,array('gif','jpeg','jpg','png','bmp','js','html','htm','shtml')))
{
    
//抓取兄弟镜像文件保存到本地
    
writeToFile($path,fetchFile($host.$path));
 
    
//返回数据流
    
$path = dirname(__FILE__).$path;        //取本地绝对路径,避免出现不必要的错误
    
switch($ext)
    
{
        
case 'gif':
            !
function_exists('imagecreatefromjpeg') && exit();
            
header("Content-type: image/gif");
            
$im = imagecreatefromgif($path);
            
imagegif($im);
            
break;
        
case 'png':
            !
function_exists('imagecreatefromjpeg') && exit();
            
header("Content-type: image/png");
            
$im = imagecreatefrompng($path);
            
imagepng($im);
            
break;
        
case 'jpg':
        
case 'jpeg':
        
case 'bmp':
            !
function_exists('imagecreatefromjpeg') && exit();
            
header("Content-type: image/jpeg");
            
$im = imagecreatefromjpeg($path);
            
imagejpeg($im);
            
break;
        
default :
            
echo file_get_contents($path);
            
break;
    
}
    
exit();
}
 
//取远程文件内容
function fetchFile($url)
{
    
if(function_exists('curl_init'))
    
{
        
$ch = curl_init() or die(curl_error($ch));
        
curl_setopt($ch,CURLOPT_URL,$url);
        
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        
$data = curl_exec($ch) or die(curl_error($ch));
        
curl_close($ch);
    
}
    
else
    
{
        
$data = file_get_contents($url);
    
}
    
return $data;
}
 
//写入本地数据
function writeToFile($file,$data,$method = 'rb+',$isflock = 1,$ischeck = 0,$ischmod = 1)
{
    
$file = dirname(__FILE__) . $file;
    
createDir($file);
    
$ischeck && !file_exists($file) && exit('<font color="red">Forbidden!</font>');
    
touch($file);
    
$fp = fopen($file,$method);
    
$isflock && flock($fp,LOCK_EX);
    
fwrite($fp,$data);
    
$method == 'rb+' && ftruncate($fp,strlen($data));
    
flock($fp,LOCK_UN);
    
fclose($fp);
    
$ischmod && chmod($file,0755);
}
    
//取后缀
function GetExt($str)
{
    
return strtolower(substr($str,strrpos($str,'.')+1));
}
 
//创建目录
function createDir($path,$mode = 0777)
{
    
$path = dirname($path);
    
if(!is_dir($path)) createDir($path);   
    
if(!file_exists($path))
    
{
        
$mk = mkdir($path,$mode);       
        
chmod($path,$mode);
        
if(empty($mk))
        
{
            
exit('<font color="red">CreatePathFail:'.$path .'</font>');
        
}
    
}
}
 
?>

以上适用于中小型网站解决镜像同步问题,大型高并发网站还是整squid节点共享吧。

评论

发表新评论