利用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节点共享吧。
评论
发表新评论