【问题标题】:Fault-tolerant file_get_contents容错 file_get_contents
【发布时间】:2012-02-22 15:06:40
【问题描述】:

我有一个具有以下架构的网站:

End user     --->    Server A (PHP)        --->        Server B (ASP.NET & Database)
             web                    file_get_contents
           browser                  

服务器 A 是一个简单的 Web 服务器,主要服务于静态 HTML 页面。但是,有些内容是动态的,这些内容是从服务器 B 获取的。示例:

someDynamicPageOnServerA.php:
<html>
     ...static stuff...

     <?php echo file_get_contents("http://serverB/somePage.aspx?someParameter"); ?>

     ...more static stuff...
</html>

这很好用。但是,如果服务器 B 停机(维护、意外崩溃等),服务器 A 上的那些动态页面将会失败。因此,我想

  • 缓存file_get_contents的最后结果并
  • 如果 file_get_contents 超时则显示此结果。

现在,实现这样的事情应该不会太难;但是,这似乎是一种常见的情况,我想避免重新发明轮子。是否有一些 PHP 库或内置功能可以帮助这种情况?

【问题讨论】:

  • 没有内置,但很容易做到。让脚本定期获取该文件并将其保存到本地副本,然后提供该本地副本。
  • @MarcB:这是一个不错的选择。目前,我想避免这种情况,因为我希望数据库中的更改“尽快”(而不是“在下一个同步间隔”)可供网络使用。
  • 然后在您的“显示”服务器上设置一个简单的接收器服务,远程不可靠的服务器可以在进行更改后立即推送更新的数据。接收器将处理将文件写出到本地缓存副本。如果远程服务器死了,那么您只需提供陈旧的旧副本,否则您会在任何时候进行更改时获得一个新副本。
  • @MarcB:这需要更改用于修改数据库的应用程序,我宁愿避免这样做。

标签: php caching file-get-contents fault-tolerance


【解决方案1】:

我会这样做:

function GetServerStatus($site, $port){
    $fp = @fsockopen($site, $port, $errno, $errstr, 2);
    if (!$fp) {
       return false;
    } else { 
       return true;
    }
}

$tempfile = '/some/temp/file/path.txt';

if(GetServerStatus('ServerB',80)){
     $content = file_get_contents("http://serverB/somePage.aspx?someParameter");
     file_put_contents($tempfile,$content);
     echo $content;
}else{
     echo file_get_contents($tempfile);
}

【讨论】:

  • 谢谢,这很有帮助。我添加了我最终使用的解决方案作为单独的答案。
【解决方案2】:

您可以检查文件的修改时间,只有在不同时才请求它,否则加载本地副本。另外,在 PHP 网站的 cmets 中有一个用于 filemtime 的缓存伪示例(来自:http://php.net/manual/en/function.filemtime.php):

<?php
$cache_file = 'URI to cache file';
$cache_life = '120'; //caching time, in seconds

$filemtime = @filemtime($cache_file);  // returns FALSE if file does not exist
if (!$filemtime or (time() - $filemtime >= $cache_life)){
    ob_start();
    resource_consuming_function();
    file_put_contents($cache_file,ob_get_flush());
}else{
    readfile($cache_file);
}
?>

【讨论】:

    【解决方案3】:

    我接受了 dom 的回答,因为它是最有帮助的。我最终使用了一种稍微不同的方法,因为我想说明服务器可以通过端口 80 访问但其他一些问题阻止它提供请求的信息的情况。

    function GetCachedText($url, $cachefile, $timeout) {
        $context = stream_context_create(array(
         'http' => array('timeout' => $timeout)));  // set (short) timeout
    
        $contents = file_get_contents($url, false, $context);
    
        $status = explode(" ", $http_response_header[0]); // e.g. HTTP/1.1 200 OK
        if ($contents === false || $status[1] != "200") {
            $contents = file_get_contents($cachefile); // load from cache
        } else {
            file_put_contents($cachefile, $contents);  // update cache
        }
        return $contents;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 2011-02-27
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多