偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我們一起聊聊前端接口容災(zāi)

開發(fā) 前端
總結(jié)下,優(yōu)點(diǎn)包括不入侵業(yè)務(wù)代碼,不影響現(xiàn)有業(yè)務(wù),隨上隨用,盡可能避免前端純白屏的場景,成本低。劣勢包括使用局限,不適合對數(shù)據(jù)實效性比較高的業(yè)務(wù)場景,不支持 IE 瀏覽器。

開篇

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

還能咋樣,白屏唄。

有沒有不白屏的方案?

有啊,還挺簡單的。

容我細(xì)細(xì)細(xì)細(xì)分析。

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

思考

存哪里?

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

選型對比

特性

cookie

localStorage

sessionStorage

indexDB

數(shù)據(jù)生命周期

服務(wù)器或者客戶端都可以設(shè)置、有過期時間

一直存在

關(guān)閉頁面就清空

一直存在

數(shù)據(jù)儲存大小

4KB

5MB

5MB

動態(tài),很大

大于250MB

與服務(wù)器通信

每次都帶在header中

不帶

不帶

不帶

兼容性

都支持

都支持

都支持

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

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

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

因此準(zhǔn)備上云,用阿里云存儲,用 CDN 來保障。

總結(jié)下:線上 CDN、線下 IndexDB。

整體方案

整體流程圖

圖片圖片

CDN

先講講線上 CDN。

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

我們講講另外一種方案,單獨(dú)啟個 Node 服務(wù)更新 CDN 數(shù)據(jù)。

流程圖

圖片圖片

劫持邏輯

劫持所有接口,判斷接口狀態(tài)與緩存標(biāo)識。從而進(jìn)行更新數(shù)據(jù)、獲取數(shù)據(jù)、緩存策略三種操作

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

axios.interceptors.response.use(
      async (resp) => {
        const { config } = resp
        const { url } = config
        // 是否有緩存tag,用于更新CDN數(shù)據(jù)。目前是定時服務(wù)在跑,訪問頁面帶上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緩存數(shù)據(jù)已命中,請?zhí)幚韅, SentryTypeEnum.error)
            return res
          }).catch(()=>{
           pushLog(`cdn緩存數(shù)據(jù)未同步,請?zhí)幚韅, SentryTypeEnum.error)
          })
        }
      }
    );

緩存策略

累計接口異常發(fā)生 maxCount 次,打開緩存開關(guān),expiresSeconds 秒后關(guān)閉。

緩存開關(guān)用避免網(wǎng)絡(luò)波動導(dǎo)致命中緩存,設(shè)置了閥值。

/*
* 緩存策略
*/
useCache = () => {
  if (this.expiresStamp > +new Date()) {
    const d = new Date(this.expiresStamp)
    console.warn(`
    ---------------------------------------
    ---------------------------------------
    啟用緩存中
    關(guān)閉時間:${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
}

唯一標(biāo)識

根據(jù) method、url、data 三者來標(biāo)識接口,保證接口的唯一性

帶動態(tài)標(biāo)識,譬如時間戳等可以手動過濾

/**
 * 生成接口唯一鍵值
*/
generateCacheKey = (config) => {
  // 請求方式,參數(shù),請求地址,
  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`;
};

更新數(shù)據(jù)

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

Node定時任務(wù)

構(gòu)建定時任務(wù),用 puppeteer 去訪問、帶上緩存標(biāo)識,去更新 CDN 數(shù)據(jù)

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 了,基于業(yè)務(wù)簡單的增刪改查,選用 localForage 三方庫足矣。

axios.interceptors.response.use(
      async (resp) => {
        const { config } = resp
        const { url } = config
        // 是否有緩存tag,用于更新CDN數(shù)據(jù)。目前是定時服務(wù)在跑,訪問頁面帶上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緩存數(shù)據(jù)已命中,請?zhí)幚韅, SentryTypeEnum.error)
            return res
          }).catch(()=>{
           pushLog(`cdn緩存數(shù)據(jù)未同步,請?zhí)幚韅, SentryTypeEnum.error)
           if(this.isIndexDBWhiteApi(url)){
             return this.fetchIndexDB(config).then(res => {
              pushLog(`IndexDB緩存數(shù)據(jù)已命中,請?zhí)幚韅, SentryTypeEnum.error)
              return res
            }).catch(()=>{
             pushLog(`IndexDB緩存數(shù)據(jù)未同步,請?zhí)幚韅, SentryTypeEnum.error)
            })
           }
          })
        }
      }
    );

總結(jié)

總結(jié)下,優(yōu)點(diǎn)包括不入侵業(yè)務(wù)代碼,不影響現(xiàn)有業(yè)務(wù),隨上隨用,盡可能避免前端純白屏的場景,成本低。劣勢包括使用局限,不適合對數(shù)據(jù)實效性比較高的業(yè)務(wù)場景,不支持 IE 瀏覽器。

接口容災(zāi)我們也是剛弄不久,有許多細(xì)節(jié)與不足,歡迎溝通交流。

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

責(zé)任編輯:武曉燕 來源: 政采云技術(shù)
相關(guān)推薦

2025-05-26 03:15:00

接口高可用框架

2024-11-27 08:47:12

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2023-08-04 08:20:56

DockerfileDocker工具

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-06-30 08:18:51

敏捷開發(fā)模式

2023-09-10 21:42:31

2025-03-13 05:00:00

2024-02-26 00:00:00

Go性能工具

2022-11-12 12:33:38

CSS預(yù)處理器Sass

2023-12-28 09:55:08

隊列數(shù)據(jù)結(jié)構(gòu)存儲

2022-10-28 07:27:17

Netty異步Future

2022-06-26 09:40:55

Django框架服務(wù)

2023-07-27 07:46:51

SAFe團(tuán)隊測試

2023-04-26 07:30:00

promptUI非結(jié)構(gòu)化

2022-04-06 08:23:57

指針函數(shù)代碼

2022-01-04 12:08:46

設(shè)計接口

2025-03-27 02:00:00

SPIJava接口
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號