2011-08-15 110 views
3

在过去的2个月中,我一直在经历Amazon Cloudfront间歇性故障(每周2-3次),因此页面将从我的Web服务器加载,但CDN中的所有资产会在当时阻止待处理的数分钟(我证实,来自不同数据中心的shell curl有些不依赖于边缘位置 - 伦敦?)。一旦挂起的请求成功,一切都恢复正常。 我们一直在向亚马逊汇报,但他们总是回复:“不要期待我们的回复,如果gazillion的人会抱怨,那么我们会考虑寻找这样的消息。在完成支持请求之前,它通常会恢复正常操作。间歇性Cloudfront CDN故障(监控)-CDN故障转移

我得出结论,由于缺乏迁移到其他CDN的开发时间,最好的处理方式是在html头文件中添加一个脚本,以便在发生类似事件时通知我们。因此,如果请求花费的时间超过N毫秒,则在头文件中尝试从CDN下载一个小小的gif,然后调用根域内的任意url(用于监视)。

问题: 在所有流行的浏览器中,如何可靠地请求一个超时回调的文件。即:

  • 使用AJAX从CDN请求文件 - 由于跨域限制而不起作用?
  • setTimeout(“callbackTimeout”,2000)callbackTimeout(){getElementById()else ... HttpWebRequest ...} - 会被挂起的HttpWebRequest请求阻止还是会工作?

还有别的吗?

谢谢。

+0

很明显,以后可能会发展为完整的回退机制,但我们希望快速评估问题的规模。稍后,我们需要让我们的JS和CSS路径在CDN超时(或状态> = 400)上更改 - 由于相对路径,图像会随之发生......希望:) – pawpro

回答

1

这已经在IE.7 & 8,在Windows上最新的FF & OSX以及Chrome进行了简要测试。我建议你自己测试一下。缩小!如果您知道更好的方法,请提出您的改进建议。已经考虑并决定使用脚本而不是图像的方式,主要是由于我的无知。

下一个版本将在超时时写入cookie,将来的请求将在服务器端处理(使用相对资产路径)。说30分钟后,cookie将过期。每连续超时都会更新该cookie。不知道我将如何处理第一次故障转移。可能是重定向(不是很优雅但很简单)。也许我会想出更聪明的方式(可能更优雅但更复杂)。

<script type="text/javascript"> 
//<![CDATA[ 
// Absolute path to a picture on your CDN to be monitored 
cdnImagePath  = "http://YOURCDNADDRESS.net/empty.gif"; 
//this is relative path (cross domain limitation) 
//will be followed by "timeout" or "other" as a reason i.e. /cdnMonitor.php?message=timeout 
cdnMonitoringPath = "/cdnMonitor.php?message="; 
// Recommended 3000 for 3 second(s) timeout 
cdnTimeoutMilisec = 3000; 
// Set to true to be notified after timeout (provides extra information) 
cdnNotifyAfterTimeout = false; 

// Handler methods 
cdnOK = function(){ 
    if (!cdnTimer && cdnNotifyAfterTimeout) cdnNotify('success'); 
} 

cdnFail = function(reason){ 
    if (reason != "timeout") { 
      if (cdnTimer) clearTimeout(cdnTimer); 
      message = "error" 
    } else { 
      message = reason; 
    } 
    cdnNotify(message); 
} 

cdnTimeout = function() { 
    cdnTimer = false; 
    if (cdnImage.complete == false) { 
      cdnFail("timeout"); 
    } 
} 

cdnNotify = function(message) { 
    if (window.XMLHttpRequest) { 
     xmlhttp = new XMLHttpRequest(); 
     xmlhttp.open("GET", cdnMonitoringPath + message, true); 
     xmlhttp.send(); 
    } else {// code for IE6, IE5 
     xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 
} 

// Load test image and define event handlers 
cdnTimer = setTimeout("cdnTimeout()", cdnTimeoutMilisec); 
cdnImage = new Image(); 
cdnImage.onload = cdnOK; 
cdnImage.onerror = cdnFail; 
cdnImage.src = cdnImagePath + "?" + Math.floor(Math.random()*1000000); 
//]]> 
</script> 

而且这是我会使用在服务器端cdnMonitor.php特设监控:

error_log(date('Y-m-d H:i:s.') .next(explode('.',microtime(1))). ' - '. $_GET['message'] . ' - '. $_SERVER['HTTP_X_REAL_IP']. ' - ' . $_SERVER['HTTP_USER_AGENT'] ."\n", 3, '/tmp/cdnMonitor.log'); 

你需要改变“HTTP_X_REAL_IP”到REMOTE_ADDR或任何适合您的需求。我使用反向代理,这就是我所做的。

最后,我在帖子编辑器中做了一些最后一分钟的更改,可能会破坏一些东西。手指交叉。