亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

簡(jiǎn)單策略讓前端資源實(shí)現(xiàn)高可用

instein / 1665人閱讀

摘要:署名國(guó)際本文作者蘇洋創(chuàng)建時(shí)間年月日統(tǒng)計(jì)字?jǐn)?shù)字閱讀時(shí)間分鐘閱讀本文鏈接簡(jiǎn)單策略讓前端資源實(shí)現(xiàn)高可用前幾天有朋友問我,曾經(jīng)在前公司里使用過的前端資源高可用方案是怎么做的。

本文使用「署名 4.0 國(guó)際 (CC BY 4.0)」許可協(xié)議,歡迎轉(zhuǎn)載、或重新修改使用,但需要注明來源。 署名 4.0 國(guó)際 (CC BY 4.0)

本文作者: 蘇洋

創(chuàng)建時(shí)間: 2019年05月14日 統(tǒng)計(jì)字?jǐn)?shù): 6024字 閱讀時(shí)間: 13分鐘閱讀 本文鏈接: soulteary.com/2019/05/14/…


簡(jiǎn)單策略讓前端資源實(shí)現(xiàn)高可用

前幾天有朋友問我,曾經(jīng)在前公司里使用過的前端資源高可用方案是怎么做的。資源高可用聽起來應(yīng)該是后端、運(yùn)維同學(xué)的“分內(nèi)之事”。但是前端資源的高可用并沒有那么簡(jiǎn)單,在當(dāng)前復(fù)雜的網(wǎng)絡(luò)環(huán)境下,你是指望用戶多刷新幾次、還是期望用戶把Wi-Fi切換為4G,撞大運(yùn)解決問題?獲客成本如此之高的今天,放棄用戶是不明智的。

想到許久沒有寫前端相關(guān)的文章了,決定在這里簡(jiǎn)單聊聊。希望能幫助到創(chuàng)業(yè)階段的公司和團(tuán)隊(duì)。

在聊技術(shù)細(xì)節(jié)之前,我們先聊聊“什么是前端資源高可用”。

資源高可用和前端有什么關(guān)系?

前端資源高可用這個(gè)需求,對(duì)于“大廠”的同學(xué)來說應(yīng)該很陌生。

因?yàn)閷?duì)于大公司來說,有大量冗余的云主機(jī)資源可以為業(yè)務(wù)團(tuán)隊(duì)提供,并且會(huì)配套一定規(guī)模的運(yùn)維團(tuán)隊(duì)。當(dāng)監(jiān)控系統(tǒng)發(fā)現(xiàn)線上出現(xiàn)資源不可用的情況時(shí),系統(tǒng)能夠根據(jù)策略自動(dòng)切換問題資源到備份資源,而有些不能自動(dòng)切換的服務(wù),則會(huì)有值守的運(yùn)維同學(xué),在第一時(shí)間手動(dòng)進(jìn)行切換,保障業(yè)務(wù)的高可用。

而小一些規(guī)模的創(chuàng)業(yè)公司就沒那么幸運(yùn)了,資源相對(duì)緊張,甚至沒有完善的監(jiān)控措施,更別提配一只相對(duì)完善的運(yùn)維團(tuán)隊(duì)了。

或許會(huì)有人認(rèn)為,將靜態(tài)資源扔到 CDN 上后就一勞永逸了。然而現(xiàn)實(shí)世界中,網(wǎng)絡(luò)環(huán)境十分復(fù)雜,相同主機(jī)在不同線路、不同地區(qū)、不同時(shí)間段的可用性和訪問質(zhì)量是不同的,所以使用 CDN 不是解決這個(gè)問題的銀彈,但是同時(shí)使用多個(gè) CDN 或許是當(dāng)前階段比較通用的方案。

比如默認(rèn)不同地域的用戶通過不同線路訪問網(wǎng)站,如果其中一條線路出現(xiàn)問題,那么一部分用戶就無法訪問網(wǎng)站提供的服務(wù)。

這個(gè)時(shí)候,我們通常會(huì)使用切換請(qǐng)求資源服務(wù)器的方法來解決問題,比如下面這樣。

當(dāng)某條 CDN / 服務(wù)線路不正常的時(shí)候,我們可以通過切換域名來解決資源獲取不到的問題,但是別忘記一件很重要的事情:

域名生效需要時(shí)間、多地域生效周期漫長(zhǎng),在這個(gè)切換域名的時(shí)間窗口內(nèi),你的服務(wù)質(zhì)量將會(huì)持續(xù)受到影響。

并且這個(gè)方案的資源切換動(dòng)作通常會(huì)在后端進(jìn)行,而此時(shí)頁(yè)面已經(jīng)推送到用戶側(cè),資源已經(jīng)不可用,用戶需要刷新后才有可能請(qǐng)求到新的資源地址,并且是在 DNS 能夠生效的前提下,我們知道很多流行的應(yīng)用客戶端為了性能優(yōu)化,都為資源(甚至包含頁(yè)面)設(shè)置了很長(zhǎng)的有效期,可以說這個(gè)方案并不是一個(gè)很有效的方案。

所以,假設(shè)你采取類似這種方案,你必須確保下面四個(gè)條件都生效,才能達(dá)到你的目的:

你的監(jiān)控系統(tǒng)發(fā)現(xiàn)了問題,并自動(dòng)進(jìn)行了資源切換。

你的業(yè)務(wù)負(fù)責(zé)人,發(fā)現(xiàn)了問題,并手動(dòng)進(jìn)行資源切換。

你成功切換了資源,并且 DNS 快速生效(網(wǎng)絡(luò)層、客戶端層)。

你的用戶在你切換資源、DNS 生效后,恰如其分的刷新了頁(yè)面,而不是直接離開。

聽起來是不是很魔幻。

那么有沒有什么簡(jiǎn)單可靠的方案可以解決這個(gè)問題呢?

有,讓資源在前端層面進(jìn)行自動(dòng)切換。

方案簡(jiǎn)介

通過在前端環(huán)境監(jiān)聽資源加載錯(cuò)誤信息,并根據(jù)一定策略自動(dòng)加載其他位置的資源,實(shí)現(xiàn)前端依賴的資源在前端(用戶側(cè))進(jìn)行自動(dòng)切換,達(dá)到前端資源高可用的目的,減少因前端資源加載失敗而導(dǎo)致的服務(wù)不可用和用戶流失。

環(huán)境模擬

為了更直觀的演示方案如何生效,我這里使用 Docker 做一個(gè)常見場(chǎng)景的模擬。

模擬多個(gè)網(wǎng)絡(luò)

我們先創(chuàng)建一個(gè) docker-compose.yml ,里面包含下面的內(nèi)容。

version: "3"

services:

  web:
    image: ${NGX_IMAGE}
4    expose:
      - 80
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:${MAIN_HOST}"
      - "traefik.frontend.entryPoints=${SUPPORT_PROTOCOL}"
    volumes:
      - ./public/${MAIN_HOST}:/usr/share/nginx/html
    extra_hosts:
      - "${MAIN_HOST}:127.0.0.1"

  cdn1:
    image: ${NGX_IMAGE}
    expose:
      - 80
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:${CDN_HOST1}"
      - "traefik.frontend.entryPoints=${SUPPORT_PROTOCOL}"
      - "traefik.frontend.headers.customResponseHeaders=Access-Control-Allow-Origin:*"
    volumes:
      - ./public/${CDN_HOST1}:/usr/share/nginx/html
    extra_hosts:
      - "${CDN_HOST1}:127.0.0.1"

  cdn2:
    image: ${NGX_IMAGE}
    expose:
      - 80
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:${CDN_HOST2}"
      - "traefik.frontend.entryPoints=${SUPPORT_PROTOCOL}"
      - "traefik.frontend.headers.customResponseHeaders=Access-Control-Allow-Origin:*"
    volumes:
      - ./public/${CDN_HOST2}:/usr/share/nginx/html
    extra_hosts:
      - "${CDN_HOST2}:127.0.0.1"

networks:
  traefik:
    external: true

可以看到,編排文件里面定義了一個(gè)應(yīng)用網(wǎng)站,和兩個(gè) CDN 服務(wù),為了更接近真實(shí)場(chǎng)景。其中一個(gè) CDN 和應(yīng)用網(wǎng)站根域名相同、另外一個(gè)采取完全不同的域名,比如下面這樣。

# 默認(rèn)使用的鏡像
NGX_IMAGE=nginx:1.15.8-alpine
# 支持訪問的協(xié)議
SUPPORT_PROTOCOL=https,http

# 主站點(diǎn)的域名
MAIN_HOST=demo.lab.io
# 模擬根域名相同的CDN
CDN_HOST1=demo-cdn.lab.io
# 模擬根域名不同的CDN
CDN_HOST2=demo.cdn2.io

將上面的內(nèi)容保存為 .env ,并將上面內(nèi)容中的域名綁定到本地之后,執(zhí)行 docker-compose up ,就可以開始實(shí)戰(zhàn)了。

模擬常規(guī)場(chǎng)景

執(zhí)行 docker-compose up 之后,我們會(huì)看到 Docker 自動(dòng)幫我們創(chuàng)建了幾個(gè)目錄。

./public
├── demo-cdn.lab.io
├── demo.cdn2.io
└── demo.lab.io

我們?cè)?demo.lab.io 目錄下創(chuàng)建 index.html 文件,作為應(yīng)用入口。


"en">

    "UTF-8">
    "viewport" content="width=device-width, initial-scale=1.0">
    "X-UA-Compatible" content="ie=edge">
    Document
    





然后在 ./demo.lab.io/public/assets/app.js 創(chuàng)建一個(gè)腳本文件,隨便寫點(diǎn)什么,模擬被加載的資源。

document.addEventListener("DOMContentLoaded", function () {
    var p = document.createElement("p");
    p.innerText = "script excute success.";
    document.body.appendChild(p);
});

當(dāng)我們?cè)L問 http://demo.lab.io/index.html 的時(shí)候,不出意外,將會(huì)看到 由腳本輸出的 script excute success. 內(nèi)容。

我們將 ./public/demo.lab.io/assets/app.js 復(fù)制到 ./public/demo-cdn.lab.io/assets/app.js./public/demo.cdn2.io/assets/app.js 中,模擬資源分發(fā)到 CDN 的場(chǎng)景。

最簡(jiǎn)單的技術(shù)實(shí)現(xiàn)

先將上面請(qǐng)求的資源地址修改為“CDN”的地址,驗(yàn)證一下“CDN”服務(wù)是否可用。


"en">

    "UTF-8">
    "viewport" content="width=device-width, initial-scale=1.0">
    "X-UA-Compatible" content="ie=edge">
    Document
    





然后通過刪除 ./public/demo-cdn.lab.io/assets/app.js 這個(gè)腳本,模擬 CDN 資源失效的場(chǎng)景。

如果你的瀏覽器沒有奇怪的緩存行為,你將會(huì)得到一個(gè)空白的頁(yè)面,以及一行報(bào)錯(cuò)信息:

default.html:8 GET http://demo-cdn.lab.io/assets/app.js 404 (Not Found)

如果碰到域名解析錯(cuò)誤的場(chǎng)景下,我們會(huì)獲得另外一種錯(cuò)誤信息:

GET http://demo-cdn.lab.io/assets/app.js net::ERR_NAME_NOT_RESOLVED

這個(gè)時(shí)候,我們可以在頁(yè)面上做一些修改,讓它能夠在資源加載出錯(cuò)的時(shí)候,將資源切換到另外一個(gè) CDN 資源上,比如這樣:


"en">

    "UTF-8">
    "viewport" content="width=device-width, initial-scale=1.0">
    "X-UA-Compatible" content="ie=edge">
    Document
    
    





再次打開地址,你會(huì)發(fā)現(xiàn)頁(yè)面又正常了。

進(jìn)階版本

上面場(chǎng)景,我們模擬了常規(guī)場(chǎng)景下前端自動(dòng)切換資源的方式。

接下來我們來做一些小小的優(yōu)化,讓腳本加載支持更多的資源地址,達(dá)到更高的可用性。


"en">

    "UTF-8">
    "viewport" content="width=device-width, initial-scale=1.0">
    "X-UA-Compatible" content="ie=edge">
    Document
    


    


上面的實(shí)現(xiàn)中,我們將資源加載寫的更加通用,并且添加了加載成功、失敗的回調(diào),以及額外做了一個(gè)自動(dòng)切換資源的函數(shù),并將頁(yè)面腳本資源加載交給了腳本去處理。

這個(gè)方案已經(jīng)能夠解決多數(shù)場(chǎng)景下的問題了,但是如果你的資源之間存在依賴關(guān)系,又該怎么處理呢?

結(jié)合資源加載器使用

我們以 AMD 模塊規(guī)范為例,聊聊如何結(jié)合 requirejs 使用資源自動(dòng)切換。


"en">

    "UTF-8">
    "viewport" content="width=device-width, initial-scale=1.0">
    "X-UA-Compatible" content="ie=edge">
    Document

    

    


    


requirejs 引入頁(yè)面,然后使用 requirejs 方法替換 loadResource 方法后,你會(huì)發(fā)現(xiàn)似乎一切沒有什么不同。

但是你其實(shí)可以通過配置 requirejs.config 來讓資源在加載的過程中,將依賴資源先進(jìn)行下載和初始化,舉兩個(gè)實(shí)際的例子:

requirejs.config({
    map: {
        // 這是一個(gè) hack 用法,具體含義參考官方 API 文檔
        "*": { "http://demo.cdn2.io/assets/app.js": "lodash" },
    }
});
requirejs.config({
    shim:{
        // 或者這樣聲明
        "http://demo.cdn2.io/assets/app.js":{
            deps:["vue"]
        }
    }
});

當(dāng)然,你也可以改造 autoSwitch 函數(shù),自己動(dòng)態(tài)維護(hù)依賴關(guān)聯(lián)。

其他的坑

講到這里,資源自動(dòng)加載幾乎講完了,但是實(shí)際上還存在一些額外的坑。

比如結(jié)合當(dāng)前最流行的構(gòu)建工具 webpack 使用,圖片資源是一次性寫死的,需要支持動(dòng)態(tài)化。

17年的時(shí)候,我曾經(jīng)提交了一個(gè)解決方案,有興趣的同學(xué)可以圍觀一下:github.com/soulteary/w…,主要解決了 ** Not generating ouput with multiple entries** 的問題。

最后

許多看似高大上的方案,本質(zhì)其實(shí)都十分簡(jiǎn)單。與其追求高大上的概念,不如靜下心來,踏實(shí)鉆研細(xì)節(jié),思考技術(shù)到底該如何有效的服務(wù)業(yè)務(wù)、產(chǎn)生價(jià)值。

—EOF


我現(xiàn)在有一個(gè)小小的折騰群,里面聚集了一些喜歡折騰的小伙伴。

在不發(fā)廣告的情況下,我們?cè)诶锩鏁?huì)一起聊聊軟件、HomeLab、編程上的一些問題,也會(huì)在群里不定期的分享一些技術(shù)沙龍的資料。

喜歡折騰的小伙伴歡迎掃碼添加好友。(請(qǐng)注明來源和目的,否則不會(huì)通過審核)

關(guān)于折騰群入群的那些事

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/7277.html

相關(guān)文章

  • 微服務(wù)的接入層設(shè)計(jì)與動(dòng)靜資源隔離

    摘要:接入層作用一的聚合。接入層作用二服務(wù)發(fā)現(xiàn)與動(dòng)態(tài)負(fù)載均衡既然統(tǒng)一的入口變?yōu)榱私尤雽?,則接入層就有責(zé)任自動(dòng)的發(fā)現(xiàn)后端拆分,聚合,擴(kuò)容,縮容的服務(wù)集群,當(dāng)后端服務(wù)有所變化的時(shí)候,能夠?qū)崿F(xiàn)健康檢查和動(dòng)態(tài)的負(fù)載均衡。 此文已由作者劉超授權(quán)網(wǎng)易云社區(qū)發(fā)布。 歡迎訪問網(wǎng)易云社區(qū),了解更多網(wǎng)易技術(shù)產(chǎn)品運(yùn)營(yíng)經(jīng)驗(yàn)。 這個(gè)系列是微服務(wù)高并發(fā)設(shè)計(jì),所以我們先從最外層的接入層入手,看都有什么樣的策略保證高并發(fā)。...

    jindong 評(píng)論0 收藏0
  • 架構(gòu) - 收藏集 - 掘金

    摘要:淺談秒殺系統(tǒng)架構(gòu)設(shè)計(jì)后端掘金秒殺是電子商務(wù)網(wǎng)站常見的一種營(yíng)銷手段。這兩個(gè)項(xiàng)目白話網(wǎng)站架構(gòu)演進(jìn)后端掘金這是白話系列的文章。 淺談秒殺系統(tǒng)架構(gòu)設(shè)計(jì) - 后端 - 掘金秒殺是電子商務(wù)網(wǎng)站常見的一種營(yíng)銷手段。 不要整個(gè)系統(tǒng)宕機(jī)。 即使系統(tǒng)故障,也不要將錯(cuò)誤數(shù)據(jù)展示出來。 盡量保持公平公正。 實(shí)現(xiàn)效果 秒殺開始前,搶購(gòu)按鈕為活動(dòng)未開始。 秒殺開始時(shí),搶購(gòu)按鈕可以點(diǎn)擊下單。 秒殺結(jié)束后,按鈕按鈕變...

    Riddler 評(píng)論0 收藏0
  • 優(yōu)才點(diǎn)評(píng)版:架構(gòu)師們是靠什么扛住了10億個(gè)紅包?

    摘要:微信紅包的核心點(diǎn)是搖,拆,分享紅包,整個(gè)系統(tǒng)設(shè)計(jì)時(shí)必須盡最大可能保證這三個(gè)步驟一氣呵成,任何關(guān)聯(lián)系統(tǒng)出現(xiàn)異常的時(shí)候馬上進(jìn)行系統(tǒng)降級(jí),防止引起系統(tǒng)雪崩。事實(shí)上,真正支撐起微信紅包順暢運(yùn)營(yíng)的幕后英雄,正是騰訊內(nèi)部一個(gè)叫做海量之道的技術(shù)體系。 showImg(https://segmentfault.com/img/bVtam6); 編者按: 微信這么大的流量,尤其是瞬間的峰值,對(duì)于任何團(tuán)隊(duì)...

    dingding199389 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

instein

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<