成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

開篇

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

還能咋樣,白屏唄。

有沒有不白屏的方案?

有啊,還挺簡單的。

容我細細細細分析。

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

思考

存哪里?

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

選型對比

特性

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,甚至在某些場景下都不會有用戶反饋。

責任編輯:武曉燕 來源: 政采云技術
相關推薦

2024-11-27 08:47:12

2025-05-26 03:15:00

接口高可用框架

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環GolangGo

2023-08-10 08:28:46

網絡編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發模式

2022-05-24 08:21:16

數據安全API

2023-09-10 21:42:31

2025-03-13 05:00:00

2022-11-12 12:33:38

CSS預處理器Sass

2024-02-26 00:00:00

Go性能工具

2023-12-28 09:55:08

隊列數據結構存儲

2022-01-04 12:08:46

設計接口

2025-03-27 02:00:00

SPIJava接口

2023-07-27 07:46:51

SAFe團隊測試

2023-04-26 07:30:00

promptUI非結構化

2022-06-26 09:40:55

Django框架服務

2022-10-28 07:27:17

Netty異步Future

2022-02-14 07:03:31

網站安全MFA
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: heyzo在线| 亚洲免费视频在线观看 | 精品国产一区二区三区日日嗨 | 三级特黄特色视频 | av网站观看 | 日韩精品成人 | 日韩高清在线 | 日本三级日产三级国产三级 | 北条麻妃一区二区三区在线视频 | 国产精品揄拍一区二区 | 日韩有码一区二区三区 | 中文字幕av一区二区三区 | 四虎影视一区二区 | 在线欧美一区二区 | 日韩久久精品 | 成人在线电影网站 | 国产中文字幕在线观看 | 中文字幕亚洲精品 | 国产精品久久久久久久久久东京 | 亚洲精品天堂 | 欧美性视频在线播放 | 亚洲色图在线观看 | 亚洲风情在线观看 | 超碰97在线免费 | 亚洲欧美在线观看 | 欧美亚洲国产一区二区三区 | 国产精品一区二区视频 | 欧美在线一区二区视频 | av片毛片 | 韩国av网站在线观看 | 欧美最猛黑人xxxⅹ 粉嫩一区二区三区四区公司1 | 欧美高清视频一区 | 欧美午夜一区 | 人人干在线视频 | 午夜理伦三级理论三级在线观看 | 91精品国产91久久久久久密臀 | 黄频免费 | 欧美精品三区 | 亚洲精品乱码久久久久久按摩观 | 性色av一区二区三区 | 亚洲日日夜夜 |