本文博主給大家分享線上多域名實戰(zhàn),當(dāng)線上主域名不可用的情況下,啟用備用域名完成網(wǎng)站高可用保障。
網(wǎng)站的高可用性一直是網(wǎng)站運維的重中之重。一旦網(wǎng)站宕機,不僅會造成巨大的經(jīng)濟損失,也會嚴重影響用戶體驗。備份域名就是一種實現(xiàn)網(wǎng)站高可用的重要手段。通過備份域名,可以在主域名不可訪問時快速切換域名,保證網(wǎng)站正常運行。
一、前情回顧
博主上個星期,線上項目突然出現(xiàn)了少量用戶無法打開項目網(wǎng)站,技術(shù)支持聯(lián)系技術(shù)人員(也就是博主我)在用戶電腦上復(fù)現(xiàn)了這一情況。
經(jīng)過博主排查,發(fā)現(xiàn)在客戶電腦訪問主域名時,會出現(xiàn)連接超時,通過 curl 進一步分析連接詳情,舉例如下:
C:\Users\16697>curl -v www.wayn.com
* Uses proxy env variable http_proxy == 'http://11.22.11.22:4780'
* Trying 11.22.11.22:4780...
發(fā)現(xiàn)線上主域名在用戶電腦上返回的 CDN 節(jié)點 11.22.11.22
存在訪問不通的情況。博主便跟運維溝通 CDN 節(jié)點不通的問題,運維回復(fù)是 CDN 節(jié)點不通是無法避免的,要看 CDN 廠商對于用戶的覆蓋情況,建議線上項目使用多域名,并且每個域名使用不同的 CDN 廠商,最大限度避免主備域名都不可用。
OK,得到的運維的意見,我們開始著手做多域名實現(xiàn)方案。
二、購買備用域名
實現(xiàn)域名高可用解決方案,首先需要準(zhǔn)備一到兩條與主域名功能和形式相似的備份域名。如下
主域名
www.wayn.com
備用域名一
bak1.wayn.com
備用域名二
bak2.wayn.com
購買備份域名后,需要注意一下兩點:
- 需要在域名服務(wù)商那設(shè)置DNS記錄,將主域名和備份域名指向同一個IP地址。同時也需要為兩個域名設(shè)置相同的CDN加速和安全證書,保證用戶訪問體驗一致。
- 將備份域名的網(wǎng)站配置(nginx配置文件)與主域名保持一致。確保使用備份域名也可以訪問我們的網(wǎng)站。
三、主備域名切換實戰(zhàn)
這里我們介紹一下通過 JavaScript 代碼來實現(xiàn)網(wǎng)站的主備域名如何進行切換。
JavaScript 實現(xiàn)域名切換的流程如下:
- 在頁面啟動時,首先發(fā)起對主域名的請求,判斷其是否能夠正常響應(yīng)。如果啟動時主域名不可訪問,就會訪問備份域名。針對每個備用域名每隔一秒發(fā)送三次請求,如果都能訪問成功則認為備用域名可用。代碼如下:
// ES6 的模塊引入方式
import fetch from 'node-fetch'
const domain = 'https://www.wayn111.com'
const bakDomains = ['http://bak1.wayn.com', 'http://baidu.com']
masterDomainCheck()
// 主域名檢測,如果不可用會檢查備用域名是否可用
async function masterDomainCheck() {
try {
await fetch(domain)
console.log('主域名啟用成功')
} catch (e) {
// console.log(e)
try {
await getBakDomain()
console.log('備用域名可用')
} catch (e) {
console.log('備用域名也不可用')
}
}
}
// 訪問備用域名,返回其中可用的一個域名
async function getBakDomain() {
const apiPromiseList = []
for (let i = 0; i < bakDomains.length; i++) {
apiPromiseList.push(
new Promise((resolve, reject) => {
bakDomainCheck(bakDomains[i], 3, resolve, reject)
})
)
}
return await Promise.any([...apiPromiseList])
}
// 域名檢測邏輯
async function bakDomainCheck(url, count, resolve, reject) {
console.log(count)
if (count > 0) {
try {
await fetch(url)
bakDomainCheck(url, --count, resolve, reject)
} catch (e) {
console.log('e')
reject(e)
}
} else {
console.log(`bak domain:${url} access success`)
resolve({ url, count })
}
}
以上代碼經(jīng)過博主實測,大家感興趣可以將代碼拷貝在本地跑一遍。
- 如果主域名啟動時正常,則開始定時監(jiān)測主域名的可訪問性。每30秒發(fā)起一次請求,判斷主域名的HTTP狀態(tài)碼是否為200。
// 主域名正常,開始定時監(jiān)測
setInterval(() => {
fetch('https://www.wayn111.com')
.then(res => {
if (res.status !== 200) {
switchDomain()
}
})
}, 30000)
- 一旦監(jiān)測到主域名故障,開始調(diào)用 JavaScript 函數(shù),找到頁面所有包含主域名的鏈接,并將其替換為備份域名。
// 開始替換頁面內(nèi)域名為備份域名
function switchDomain() {
let links = document.querySelectorAll('a')
for (let i=0; i<links.length; i++) {
if (links[i].href.indexOf('https://www.wayn111.com') > -1) {
links[i].href = links[i].href.replace('https://www.wayn111.com'
, 'https://bak1.wayn.com')
}
}
}
- 繼續(xù)定時監(jiān)測主域名,在主域名恢復(fù)正常時,調(diào)用 JavaScript 函數(shù)將備份域名的鏈接替換回主域名。
// 定時檢查主域名故障恢復(fù),一旦恢復(fù)再切回主域名
setInterval(() => {
fetch('https://www.wayn111.com')
.then(res => {
if (res.status === 200) {
switchDomainBack()
}
})
}, 5000)
function switchDomainBack() {
let links = document.querySelectorAll('a')
for (let i=0; i<links.length; i++) {
if (links[i].href.indexOf('https://bak1.wayn.com') > -1) {
links[i].href = links[i].href.replace('https://bak1.wayn.com'
, 'https://www.wayn111.com')
}
}
}
- 這樣通過 JavaScript 檢測域名狀態(tài)與自動切換,可以最大限度減少域名切換造成的訪問中斷時間,確保網(wǎng)站高可用。
希望大家通過這個案例,能對線上用多域名來實現(xiàn)高可用網(wǎng)站有一個較為全面的認知。網(wǎng)站過于依賴某單一域名存在潛在風(fēng)險,備份域名的引入主要是解決少數(shù)場景下用戶訪問不通我們網(wǎng)站的問題。
最后感謝大家閱讀,喜歡的朋友可以點贊加關(guān)注,你的支持將是我的更新動力??。文章來源:http://www.zghlxwxcb.cn/news/detail-421758.html
公眾號【waynblog】每周更新技術(shù)干貨、線上項目實戰(zhàn)經(jīng)驗、高效開發(fā)工具等。文章來源地址http://www.zghlxwxcb.cn/news/detail-421758.html
到了這里,關(guān)于線上多域名實戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!