背景
之前遇到一个棘手的问题,需要做一个多个数据中心的灾备方案,但是目前没有DNS供使用。
每个浏览器都是直接访问单个中心的F5设备。这就导致一个问题,一旦该浏览器访问的中心宕机,则该客户端就没有办法使用了服务了,获取不到最初的页面。
解决方案
基于互联网移动解决方案的,制定了如下的解决方案。通过浏览器的新特性,保证浏览器在无网状态下也可以访问到部分服务。
无网状态下服务访问功能基于H5的service worker
技术来缓存一个负载页面
,从而进行多中心的灾备负载访问。
- 第一步:访问单中心的服务,在服务的主页,注册一个
service worker
- 第二步:在
service worker
的代码中,对负载页面(/failover.html)
进行缓存。 - 第三步:在
负载页面(/failover.html)
中,通过XMLHttpRequest
对多个中心进行探活,一旦某个中心探活成功,则跳转到该中心进行服务访问。
具体实现
- login.html
<script src="failover/app.js"></script>
- failover/app.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('failover/sw.js', { scope: '/'
}).then(function(reg) {
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
}
- failover/sw.js
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open('failover').then(function(cache) {
return cache.addAll([
'failover/failover.html'
]);
})
);
});
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request).then(function(response) {
if (response !== undefined) {
return response;
} else {
return fetch(event.request).then(function (response) {
return response;
}).catch(function () {
return caches.match('failover/failover.html');
});
}
}));
});
- failover/failover.html
<html>
<head>
<title>Failover</title>
</head>
<body>
<h1>当前数据中心无法访问,正在为您转接。。。</h1>
<script>
window.onload = function() {
let backupURLs = ['http://somehost1.com/', 'http://somehost2.com/', 'http://somehost3.com/'];
backupURLs.forEach(url => {
//AJAX探活,如果活,则window.location.href = url;
})
}
</script>
</html>
网友评论