日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

開篇

你說,萬一接口掛了會怎么樣?

還能咋樣,白屏唄。

有沒有不白屏的方案?

有啊,還挺簡單的。

容我細細細細分析。

原因就是接口掛了,拿不到數據了。那把數據儲存起來就可以解決問題。

思考

存哪里?

第一時間反應瀏覽器本地存儲,想起了四兄弟。

選型對比

特性

cookie

localStorage

sessionStorage

indexDB

數據生命周期

服務器或者客戶端都可以設置、有過期時間

一直存在

關閉頁面就清空

一直存在

數據儲存大小

4KB

5MB

5MB

動態,很大

大于250MB

與服務器通信

每次都帶在header中

不帶

不帶

不帶

兼容性

都支持

都支持

都支持

IE不支持,其他主流都支持

考慮到需要存儲的數據量,5MB 一定不夠的,所以選擇了 IndexDB。

考慮新用戶或者長時間未訪問老用戶,會取不到緩存數據與陳舊的數據。

因此準備上云,用阿里云存儲,用 CDN 來保障。

總結下:線上 CDN、線下 IndexDB。

整體方案

整體流程圖

我們一起聊聊前端接口容災圖片

CDN

先講講線上 CDN。

通常情況下可以讓后端支撐,本質就是更新策略問題,這里不細說。

我們講講另外一種方案,單獨啟個 Node 服務更新 CDN 數據。

流程圖

我們一起聊聊前端接口容災圖片

劫持邏輯

劫持所有接口,判斷接口狀態與緩存標識。從而進行更新數據、獲取數據、緩存策略三種操作

通過配置白名單來控制接口存與取

axIOS.interceptors.response.use(
      async (resp) => {
        const { config } = resp
        const { url } = config
        // 是否有緩存tag,用于更新CDN數據。目前是定時服務在跑,訪問頁面帶上tag
        if (this.hasCdnTag() && this.isWhiteApi(url)) {
          this.updateCDN(config, resp)
        }
        return resp;
      },
      async (err) => {
        const { config } = err
        const { url } = config
        // 是否命中緩存策略
        if (this.isWhiteApi(url) && this.useCache()) {
          return this.fetchCDN(config).then(res => {
            pushLog(`cdn緩存數據已命中,請處理`, SentryTypeEnum.error)
            return res
          }).catch(()=>{
           pushLog(`cdn緩存數據未同步,請處理`, SentryTypeEnum.error)
          })
        }
      }
    );

緩存策略

累計接口異常發生 maxCount 次,打開緩存開關,expiresSeconds 秒后關閉。

緩存開關用避免網絡波動導致命中緩存,設置了閥值。

/*
* 緩存策略
*/
useCache = () => {
  if (this.expiresStamp > +new Date()) {
    const d = new Date(this.expiresStamp)
    console.warn(`
    ---------------------------------------
    ---------------------------------------
    啟用緩存中
    關閉時間:${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}
    ---------------------------------------
    ---------------------------------------
    `)
    return true
  }
  this.errorCount += 1
  localStorage.setItem(CACHE_ERROR_COUNT_KEY, `${this.errorCount}`)
  if (this.errorCount > this.maxCount) {
    this.expiresStamp = +new Date() + this.expiresSeconds * 1000
    this.errorCount = 0
    localStorage.setItem(CACHE_EXPIRES_KEY, `${this.expiresStamp}`)
    localStorage.removeItem(CACHE_ERROR_COUNT_KEY)
    return true
  }
  return false
}

唯一標識

根據 method、url、data 三者來標識接口,保證接口的唯一性

帶動態標識,譬如時間戳等可以手動過濾

/**
 * 生成接口唯一鍵值
*/
generateCacheKey = (config) => {
  // 請求方式,參數,請求地址,
  const { method, url, data, params } = config;
  let rawData = ''
  if (method === 'get') {
    rawData = params
  }
  if (method === 'post') {
    rawData = JSON.parse(data)
  }
  // 返回拼接key
  return `${encodeURIComponent([method, url, stringify(rawData)].join('_'))}.json`;
};

更新數據

/**
 * 更新cdn緩存數據
*/
updateCDN = (config, data) => {
  const fileName = this.generateCacheKey(config)
  const cdnUrl = `${this.prefix}/${fileName}`
  axios.post(`${this.nodeDomAIn}/cdn/update`, {
    cdnUrl,
    data
  })
}

Node定時任務

構建定時任務,用 puppeteer 去訪問、帶上緩存標識,去更新 CDN 數據

import schedule from 'node-schedule';

const scheduleJob = {};

export const xxxJob = (ctx) => {
  const { xxx } = ctx.config;
  ctx.logger.info(xxx, 'xxx');
  const { key, url, rule } = xxx;
  if (scheduleJob[key]) {
    scheduleJob[key].cancel();
  }
  scheduleJob[key] = schedule.scheduleJob(rule, async () => {
    ctx.logger.info(url, new Date());
    await browserIndex(ctx, url);
  });
};

export const browserIndex = async (ctx, domain) => {
  ctx.logger.info('browser --start', domain);
  if (!domain) {
    ctx.logger.error('domain為空');
    return false;
  }
  const browser = await puppeteer.launch({
    args: [
      '--use-gl=egl',
      '--disable-gpu',
      '--no-sandbox',
      '--disable-setuid-sandbox',
    ],
    executablePath: process.env.CHROMIUM_PATH,
    headless: true,
    timeout: 0,
  });
  const page = await browser.newPage();
  await page.goto(`${domain}?${URL_CACHE_KEY}`);
  await sleep(10000);
  // 訪問首頁所有查詢接口
  const list = await page.$$('.po-tabs__item');
  if (list?.length) {
    for (let i = 0; i < list.length; i++) {
      await list[i].click();
    }
  }
  await browser.close();
  ctx.logger.info('browser --finish', domain);
  return true;
};

效果

手動 block 整個 domain,整個頁面正常展示

我們一起聊聊前端接口容災圖片

IndexDB

線上有 CDN 保證了,線下就輪到 IndexDB 了,基于業務簡單的增刪改查,選用 localForage 三方庫足矣。

axios.interceptors.response.use(
      async (resp) => {
        const { config } = resp
        const { url } = config
        // 是否有緩存tag,用于更新CDN數據。目前是定時服務在跑,訪問頁面帶上tag
        if (this.hasCdnTag() && this.isWhiteApi(url)) {
          this.updateCDN(config, resp)
        }
        if(this.isIndexDBWhiteApi(url)){
          this.updateIndexDB(config, resp)
        }
        return resp;
      },
      async (err) => {
        const { config } = err
        const { url } = config
        // 是否命中緩存策略
        if (this.isWhiteApi(url) && this.useCache()) {
          return this.fetchCDN(config).then(res => {
            pushLog(`cdn緩存數據已命中,請處理`, SentryTypeEnum.error)
            return res
          }).catch(()=>{
           pushLog(`cdn緩存數據未同步,請處理`, SentryTypeEnum.error)
           if(this.isIndexDBWhiteApi(url)){
             return this.fetchIndexDB(config).then(res => {
              pushLog(`IndexDB緩存數據已命中,請處理`, SentryTypeEnum.error)
              return res
            }).catch(()=>{
             pushLog(`IndexDB緩存數據未同步,請處理`, SentryTypeEnum.error)
            })
           }
          })
        }
      }
    );

總結

總結下,優點包括不入侵業務代碼,不影響現有業務,隨上隨用,盡可能避免前端純白屏的場景,成本低。劣勢包括使用局限,不適合對數據實效性比較高的業務場景,不支持 IE 瀏覽器。

接口容災我們也是剛弄不久,有許多細節與不足,歡迎溝通交流。

接口容災本意是預防發生接口服務掛了的場景,我們不會很被動。原來是P0的故障,能被它降低為 P2、P3,甚至在某些場景下都不會有用戶反饋。

分享到:
標簽:接口
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定