2012-02-22 1 views
2

J'ai un site Web avec l'architecture suivante:file_get_contents tolérance de pannes

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

serveur A est un simple serveur web, la plupart du temps au service des pages HTML statiques. Toutefois, certains contenus sont dynamiques et ce contenu est extrait du serveur B. Exemple:

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

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

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

Cela fonctionne correctement. Cependant, si le serveur B est en panne (maintenance, crash inattendu, etc.), ces pages dynamiques sur le serveur A échoueront. Ainsi, je voudrais

  • cache le dernier résultat de file_get_contents et
  • montrent ce résultat si file_get_contents timeouted.

Maintenant, il ne devrait pas être trop difficile d'implémenter quelque chose comme ça; Cependant, cela semble être un scénario commun et je voudrais éviter de réinventer la roue. Existe-t-il une bibliothèque PHP ou une fonctionnalité intégrée qui aide à ce qu'un tel scénario?

+0

Rien de construit, mais c'est assez facile à faire. Demandez à un script de récupérer périodiquement ce fichier et de l'enregistrer dans une copie locale, et de servir cette copie locale à la place. –

+0

@MarcB: C'est une bonne alternative. Pour le moment, je voudrais éviter cela, car je veux que les changements dans la base de données soient disponibles sur le web "le plus rapidement possible" (et non "au prochain intervalle de synchronisation"). – Heinzi

+0

Ensuite, configurez un service de réception simple sur votre serveur «d'affichage», sur lequel le serveur distant non fiable peut pousser les données mises à jour dès qu'un changement est effectué. Le destinataire va gérer l'écriture du fichier dans une copie de cache locale. Si le serveur distant meurt, vous devez simplement en conserver une copie ancienne, sinon vous en recevrez une nouvelle copie chaque fois qu'une modification est effectuée. –

Répondre

2

je ferais quelque chose comme ceci:

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); 
} 
+0

Merci, cela a été utile. J'ai ajouté la solution que j'ai fini par utiliser comme une réponse séparée. – Heinzi

0

Vous pouvez vérifier le temps modifiée du fichier et ne demander quand il est différent, sinon charger la copie locale. En outre, il y a un pseudo-exemple de cache sur le site Web de PHP dans les commentaires pour filemtime (à partir de: 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); 
} 
?> 
0

j'ai accepté la réponse de dom, puisqu'il était le plus utile. J'ai fini par utiliser une approche légèrement différente, puisque je voulais rendre compte de la situation où le serveur est accessible via le port 80, mais un autre problème l'empêche de servir les informations demandées.

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; 
} 
Questions connexes