Skip to content
0

CDN 容灾

CDN(Content Delivery Network),即内容分发网络。

CDN 是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术。

不同资源的容灾方案

JS

对于直接放在 HTML 中的 script 标签,可以通过 onerror 事件来捕获错误,并更换 src 属性为备用 HOST 的 URL。

<body>
    <script>
        function handleError(e) {
            console.error('Script load failed', e.srcElement);
            e.srcElement.src = /* 使用备用 HOST 的 URL */'';
        }
    </script>
    <!-- 直接放在 HTML 中的 script 标签 -->
    <script src="https://example.com/nonexistent-script.js" onerror="handleError(event)"></script>
</body>

<!-- 或者 -->
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var scripts = document.getElementsByTagName('script');

    for (var i = 0; i < scripts.length; i++) {
      scripts[i].addEventListener('error', function () {
        console.error('Script load failed:', this.src)
        this.src = /* 使用备用 HOST 的 URL */''
      })
    }
  })
</script>

对于动态插入的 JS 文件,可以通过 onerror 事件来捕获错误,并更换 src 属性为备用 HOST 的 URL。

function loadScript(url, callback) {
  const script = document.createElement('script')
  script.type = 'text/javascript'
  script.src = url

  script.onload = function () {
    callback(null) // 加载成功
  }

  script.onerror = function () {
    script.src = /* 使用备用 HOST 的 URL */''
  }

  document.head.appendChild(script)
}

loadScript('https://example.com/script.js')

CSS

同上面 JS 的容灾方案。

图片

同上面 JS 的容灾方案,支持 new Image() 的方式:

const OriginalImage = Image

// 重写 Image 构造函数
window.Image = function () {
  const img = new OriginalImage()

  img.onerror = function () {
    // 更换 src 属性为备用 HOST 的 URL
    this.src = /* 使用备用 HOST 的 URL */''
  }

  return img
}

Ajax

针对于请求的重试,需要统一请求的方式,使用封装好的 axios 或者 fetch 请求,例如,在 axios,针对请求失败后更换域名的重试如下:

// 添加一个响应拦截器
instance.interceptors.response.use(null, (error) => {
  const originalRequest = error.config

  // 如果请求失败并且响应状态码为 500 或者 503
  if (error.response.status === 500 || error.response.status === 503) {
    // 更换域名
    originalRequest.baseURL = 'https://new-domain.com'

    // 重试请求
    return instance(originalRequest)
  }

  return Promise.reject(error)
})

CSS / Style 中的资源

例如字体,背景图等,思路为:

  • 为 link 标签添加 crossorigin 属性,允许跨域资源可读;
  • 定时轮询新增的样式表(document.stylesheets)
  • 更换样式表中 url() 函数的CDN异常域名,在样式表尾部追加样式规则覆盖。

具体方案

Released under the MIT License.