互联网服务 2012 年 5 月 2 日

给WordPress配置冗余附件服务器

本文介绍了如何提高网站图片和附件的可用性,通过增加一个冗余的附件服务器来保证网站的高可用性。文章详细介绍了系统的结构和工作原理,以及解决系统实现中需要考虑的两个问题:如何保证附件服务器1和附件服务器2的内容一致,以及在附件服务器1挂掉之后如何将附件地址改为附件服务器2的地址。最后还介绍了使用WordPress插件来解决第一个问题的方法。
经常使用图床的朋友可能担心某一天图床被删除,导致网站的图片和附件丢失,从而给读者留下一个非常糟糕的印象。
为了保证图片和附件的高可用性,除了选一个稳定的图床外,我们还可以增加一个冗余的附件服务器。这样即使图床挂了,我们的冗余附件服务器还能正常工作,这样就保证了网站图片和附件的可访问性。整个系统的结构如下图所示:
System Topology
上图中的Main Server是主服务器,Attachment Server 1就是我们的图床,Attachment Server 2是备份的附件服务器。
主服务器负责客户请求的处理,并将结果返回给客户端,比如输出一篇带有图片和附件链接的文章; 附件服务器1和附件服务器2的内容是完全相同的,正常情况下,Main Server返回给客户端内容的图片和附件链接都指向附件服务器1,比如有一张图片链接为:http:// upload .shuyz.com/2012/04/search.png,那么浏览器会向附件服务器1请求这个图片;如果附件服务器1挂掉了,那么所有的附件地址将指向附件服务器2,这张图片的地址应该变成http:// uploadmirror .shuyz.com/2012/04/search.png,浏览器在附件服务器2(备份附件服务器)中仍然能请求到这张图片。
你可能会问,如果附件服务器2也挂了呢?再仔细看一下上面的拓扑图,我用虚线将Attachment Server 2和 Mian Server使用圈起来了,它们实际上在同一台服务器上。也就是说只要能主站能访问,附件服务器2就能访问;如果附件服务器挂了,那么表示主站也不能访问了。
现在你可能已经想到要实现这个系统需要解决的两个问题:
1、如何保证附件服务器1和附件服务器2的内容一致?
2、在附件服务器1 挂掉之后,如何将附件地址改为附件服务器2的地址?
第一个问题我们可以使用WordPress插件解决,你可以使用WordPress 插件Hacklog Remote Attachment Sync 或 W3C Total Cache 来实现通过FTP将图片和附件同步。关于Hacklog Remote Attachment Sync的使用作者博客里有详细教程,你也可以参考我以前的一篇文章:WordPress 附件FTP同步插件—Hacklog Remote Attachment
第二个问题有点麻烦,暂时想到两种方案:

方案1:网页文本加载完成后在客户端使用javascript ping图床(附件服务器1),如果ping不通就说明图床挂掉,并将网页中所有指向图床的地址改成附件服务器2的地址,这样浏览器就能像附件服务器2请求图片和附件了。一切全是智能的。看似看美好,但由于不熟悉javascript的使用,最终放弃了这种方案。。 … 方案2:用户如果看到图片不能加载,可以点击一个按钮告诉主服务器”图床”已经不能访问,主服务器接受到这个信息后改用附件服务器2提供图片和附件,用户的信息记录在cookie中,这样用户点击一次,以后每次向主服务器请求数据时都带了这个信息。主服务器就可以自动处理了。 为了方便描述,下文我们将附件服务器1成为server1,附件服务器2成为sever2.方案2的原理如下图所示:

work flowchart
从上图可以看出,我们要做的油两个步骤,一是将用户设置的附件服务器信息保存在cookies中,二是在服务器端判断cookies的服务器信息,从而决定使用哪个附件服务器。

步骤1 客户端附件服务器Cookies的设置

我们让用户点击按钮后,通过jquery给服务器端 post一个数据,服务器在给客户端发一个设置cookies 的信息。
服务器端设置用户浏览器cookies的实现(通过post或get接收数据):
<?php  
  
/** 
 * @file    wp-attach-svr.php 
 * @brief   receive data via post or get method, switch svr if any data received,  
 *          or show current server if there is no parameter 
 * @version v1.1 
 * @data    2012-05-12 
 *  
 */   
  
    // post/get parameter  
    if(isset($_POST['attach-svr']) || isset($_GET['attach-svr'])) {  
          
        $my_svr = '';  
          
        if ( isset( $_COOKIE['attach_server']) && ('server2' == $_COOKIE['attach_server'])) {  
            setcookie('attach_server','server1');  
            $my_svr = 'Changed to server1, refreshing...';  
        }  
          
        else {  
            setcookie('attach_server','server2');  
            $my_svr = 'Changed to server2, refreshing...';  
        }  
          
        echo $my_svr;  
    }  
      
    // no parameter, show current server name  
    else {  
          
        if (isset( $_COOKIE['attach_server']) ) {  
            echo 'Current server: ' . $_COOKIE['attach_server'];  
        }  
          
        else {  
            echo 'Current server: default';  
        }  
    }  
      
?>  
将上面的代码保存为wp-attach-svr.php文件,用户使参数访问这个文件就可以切换cookie里的附件服务器设置信息,从而在两个附件服务器中循环切换。
下面我们要做的就是读取这个信息,然后根据cookie设置来改变附件的链接。

步骤2 服务器对Cookies信息的判断

在functions.php 加上:
function switch_attach_mirrror(){  
    if  ("server2" == $_COOKIE["attach_server"] )  
        {  
            add_filter("the_content", change_attach_url);  
        }  
}  
  
function change_attach_url($content) {  
    $content = str_replace('upload.shuyz.com', 'uploadmirror.shuyz.com',$content);  
    return $content;  
}  
在header里调用 switch_attach_mirrror() 函数就可以了。
这样就实现了附件服务器1和附件服务器2的自由切换,即使图床没挂掉,用户依然可以切换到速度稍微快一点的附件服务器2。效果见本站右上角的附件服务器信息。