線上多域名實戰

2023-04-23 06:01:15

本文博主給大家分享線上多域名實戰,當線上主域名不可用的情況下,啟用備用域名完成網站高可用保障。

網站的高可用性一直是網站運維的重中之重。一旦網站宕機,不僅會造成巨大的經濟損失,也會嚴重影響使用者體驗。備份域名就是一種實現網站高可用的重要手段。通過備份域名,可以在主域名不可存取時快速切換域名,保證網站正常執行。

一、前情回顧

博主上個星期,線上專案突然出現了少量使用者無法開啟專案網站,技術支援聯絡技術人員(也就是博主我)在使用者電腦上覆現了這一情況。

經過博主排查,發現在客戶電腦存取主域名時,會出現連線超時,通過 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...

發現線上主域名在使用者電腦上返回的 CDN 節點 11.22.11.22 存在存取不通的情況。博主便跟運維溝通 CDN 節點不通的問題,運維回覆是 CDN 節點不通是無法避免的,要看 CDN 廠商對於使用者的覆蓋情況,建議線上專案使用多域名,並且每個域名使用不同的 CDN 廠商,最大限度避免主備域名都不可用。

OK,得到的運維的意見,我們開始著手做多域名實現方案。

二、購買備用域名

實現域名高可用解決方案,首先需要準備一到兩條與主域名功能和形式相似的備份域名。如下

主域名
www.wayn.com

備用域名一
bak1.wayn.com

備用域名二
bak2.wayn.com

購買備份域名後,需要注意一下兩點:

  1. 需要在域名服務商那設定DNS記錄,將主域名和備份域名指向同一個IP地址。同時也需要為兩個域名設定相同的CDN加速和安全證書,保證使用者存取體驗一致。
  2. 將備份域名的網站設定(nginx組態檔)與主域名保持一致。確保使用備份域名也可以存取我們的網站。

三、主備域名切換實戰

這裡我們介紹一下通過 JavaScript 程式碼來實現網站的主備域名如何進行切換。

JavaScript 實現域名切換的流程如下:

  1. 在頁面啟動時,首先發起對主域名的請求,判斷其是否能夠正常響應。如果啟動時主域名不可存取,就會存取備份域名。針對每個備用域名每隔一秒傳送三次請求,如果都能存取成功則認為備用域名可用。程式碼如下:
// 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 })
  }
}

以上程式碼經過博主實測,大家感興趣可以將程式碼拷貝在本地跑一遍。

  1. 如果主域名啟動時正常,則開始定時監測主域名的可存取性。每30秒發起一次請求,判斷主域名的HTTP狀態碼是否為200。
// 主域名正常,開始定時監測
setInterval(() => {
  fetch('https://www.wayn111.com')
    .then(res => {
      if (res.status !== 200) {
        switchDomain() 
      }
    })  
}, 30000)
  1. 一旦監測到主域名故障,開始呼叫 JavaScript 函數,找到頁面所有包含主域名的連結,並將其替換為備份域名。
// 開始替換頁面內域名為備份域名
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')
    }
  }
}
  1. 繼續定時監測主域名,在主域名恢復正常時,呼叫 JavaScript 函數將備份域名的連結替換回主域名。
// 定時檢查主域名故障恢復,一旦恢復再切回主域名  
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')
    }
  }
}
  1. 這樣通過 JavaScript 檢測域名狀態與自動切換,可以最大限度減少域名切換造成的存取中斷時間,確保網站高可用。

希望大家通過這個案例,能對線上用多域名來實現高可用網站有一個較為全面的認知。網站過於依賴某單一域名存在潛在風險,備份域名的引入主要是解決少數場景下使用者存取不通我們網站的問題。

最後感謝大家閱讀,喜歡的朋友可以點贊加關注,你的支援將是我的更新動力