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

卡口服務(wù)——基于前端巡檢系統(tǒng)的拓展實踐

開發(fā) 架構(gòu)
對于卡口服務(wù)來說,學(xué)習(xí)和閱讀巡檢的源碼是一個重要的前置工作。通過深入理解巡檢系統(tǒng)的實現(xiàn)細(xì)節(jié)和底層架構(gòu)設(shè)計可以更好地理解巡檢系統(tǒng)是如何工作的,從而更好地進行定制和擴展,這些經(jīng)驗也幫助提升了自己的編碼能力和設(shè)計能力,在后續(xù)的技術(shù)項目中可以得到應(yīng)用和實踐。

一、背景

體驗是得物的業(yè)務(wù)關(guān)鍵詞之一,對于前端開發(fā)而言,提高用戶體驗更是重要工作內(nèi)容之一。

得物前端平臺目前有巡檢系統(tǒng)、監(jiān)控平臺等多種手段保障線上頁面穩(wěn)定運行,但是仍有一部分問題處于“監(jiān)控死角”,而且巡檢、監(jiān)控都屬于后置告警手段,為了確保頁面上線前就能得到一定的用戶體驗保障,結(jié)合公司的戰(zhàn)略目標(biāo),我們決定開發(fā)一個H5頁面檢測服務(wù),用來前置檢測即將上線的頁面,提前暴露該頁面可能存在的問題反饋給對應(yīng)的開發(fā)/運營,我們將這個服務(wù)稱之為:“體驗卡口”。

本文從這次“體驗卡口”服務(wù)的開發(fā)實踐出發(fā),同時介紹得物巡檢系統(tǒng)的架構(gòu)和設(shè)計,希望能給參與穩(wěn)定性建設(shè)的開發(fā)小伙伴提供一定的學(xué)習(xí)和參考價值。

二、用戶體驗量化標(biāo)準(zhǔn)

當(dāng)我們試圖量化影響用戶體驗的問題時,需要思考以下兩個主要問題:

什么影響了用戶體驗?

我們已經(jīng)通過豐富的數(shù)據(jù)支撐和實踐經(jīng)驗,對影響用戶體驗的因素有了深入了解。從過去的線上問題反饋收集和開發(fā)經(jīng)驗中,我們將體驗問題大致分為兩個等級:

  1. P0級:這些問題嚴(yán)重影響頁面加載速度或涉及到安全風(fēng)險,例如頁面包含超大的圖片/媒體資源、頁面中含有個人隱私信息;
  2. P1級:這些問題可能對用戶體驗造成潛在影響,例如頁面中存在響應(yīng)時間超過300ms的接口請求。

如何檢測以及量化問題?

一旦我們對體驗問題進行了定義和分級,接下來需要建立適當(dāng)?shù)臋C制來檢測這些問題。對于卡口服務(wù),我們可以采取以下步驟來量化問題、轉(zhuǎn)換為可執(zhí)行的檢測代碼,并通過卡口服務(wù)生成相應(yīng)的檢測報告供調(diào)用方使用:

  1. 確定指標(biāo)和標(biāo)準(zhǔn):首先,我們需要確定用于量化體驗問題的指標(biāo)和標(biāo)準(zhǔn)。例如,對于接口請求速度問題,可以使用接口響應(yīng)時間作為指標(biāo),同時設(shè)定一定的標(biāo)準(zhǔn),例如超過特定時間閾值即視為問題。
  2. 編寫自動化腳本:基于指標(biāo)和標(biāo)準(zhǔn),我們可以編寫自動化腳本來模擬用戶在無頭瀏覽器中執(zhí)行相關(guān)操作,例如加載頁面、點擊按鈕、發(fā)送請求等。這些腳本將根據(jù)設(shè)定的指標(biāo)進行性能測量和問題檢測。
  3. 使用無頭瀏覽器執(zhí)行測試:我們可以在無頭瀏覽器中運行自動化腳本,模擬用戶行為并收集相應(yīng)的性能數(shù)據(jù)。
  4. 結(jié)果分析和報告生成:通過收集的性能數(shù)據(jù),我們可以進行結(jié)果分析,并將問題和相關(guān)數(shù)據(jù)轉(zhuǎn)化為檢測報告。該報告可以包括問題的詳細(xì)描述、問題等級、相關(guān)性能指標(biāo)和數(shù)據(jù)。
  5. 提供給調(diào)用方:最后,通過卡口服務(wù),我們可以將生成的檢測報告提供給調(diào)用方。調(diào)用方可以根據(jù)報告中的問題和數(shù)據(jù)進行相應(yīng)的優(yōu)化和改進,以提升用戶體驗。

這樣的機制可以幫助我們自動化地檢測和量化體驗問題,并提供可執(zhí)行的檢測代碼和相關(guān)報告。這樣一來,我們可以更有效地識別和解決問題,并提供準(zhǔn)確的數(shù)據(jù)給予開發(fā)團隊進行優(yōu)化。

以下是我們整理出需要具體實現(xiàn)的檢測case:

圖片

收集完具體的影響用戶體驗的case之后,要確定具體的開發(fā)方案,由于卡口服務(wù)與得物前端平臺巡檢系統(tǒng)有很多技術(shù)實現(xiàn)重合的部分,所以我們決定利用現(xiàn)有的巡檢架構(gòu),將“體驗卡口”集成到現(xiàn)有的巡檢系統(tǒng)中,可以節(jié)省大量的開發(fā)時間。

3、巡檢系統(tǒng)基礎(chǔ)架構(gòu)

巡檢系統(tǒng)的程序目標(biāo)一句話總結(jié):定時從數(shù)據(jù)源獲取待檢測頁面地址列表,然后進行批量檢測并生成報告。

為了應(yīng)對不同場景下的個性化需求,巡檢系統(tǒng)抽象出了三個巡檢器基類,各場景繼承基類實現(xiàn)定制需求。

3.1 巡檢器基類

  1. DataProviderBase(數(shù)據(jù)提供基類):
  • dataSlim(): 簡化冗余數(shù)據(jù);
  • fetchData():獲取遠(yuǎn)程數(shù)據(jù),處理并返回待檢測頁面url列表;
  • isSkipTime():用來設(shè)置條件,在某些特定條件下跳過定時任務(wù);
  • schedule():設(shè)置定時任務(wù)運行區(qū)間;

圖片

  1. PageInspectorBase(頁面檢查器基類):
  • check():檢查器入口,用來打開指定的檢測頁面,并初始化各種資源的監(jiān)聽;
  • injectRequestHeaders():注入頁面接口請求需要的cookie、token等;
  • urlCheck():url地址檢查;
  • onRequest():監(jiān)聽頁面請求;
  • onResponse():監(jiān)聽頁面響應(yīng);
  • onPageError():監(jiān)聽頁面錯誤;

圖片

  1. DataReporterBase(數(shù)據(jù)報告基類):
  • buildReporter(): 根據(jù)采集到的錯誤信息生成檢測報告;
  • feishuNotify():將生成的報告通過飛書發(fā)送到指定的通知群;
  • getHTMLReporterUrl():根據(jù)ejs模板將報告生成html靜態(tài)文件并上傳,返回在線報告地址;

圖片

我們可以形象地將這三個基類比成一家飯店的三個不同分工的部門,能更方便地去理解它:

飯店前臺負(fù)責(zé)接收顧客提供的訂單,后廚根據(jù)訂單下料炒菜裝盤,服務(wù)員將做好的飯菜提供給顧客。

DataProviderBase(數(shù)據(jù)提供基類):負(fù)責(zé)定時輪詢接收外部提供的待檢測頁面列表。這個組件類似于飯店前臺,接收顧客提供的訂單。它負(fù)責(zé)從外部獲取待檢測的頁面列表,并將這些頁面?zhèn)鬟f給檢測器進行檢測。

PageInspectorBase(頁面檢查器基類):逐一檢測頁面列表中的每一個URL,并檢測頁面中的潛在問題。類似于后廚根據(jù)訂單下料、炒菜和裝盤的過程,這個組件負(fù)責(zé)逐個檢測待檢測頁面列表中的URL,并對每個頁面進行問題檢測。它可以使用一系列的檢測方法和規(guī)則,以確定頁面是否存在潛在問題。

DataReporterBase(數(shù)據(jù)報告基類):將檢測搜集的問題進一步整理后發(fā)送報告。類似于服務(wù)員將做好的飯菜提供給顧客,這個組件負(fù)責(zé)將經(jīng)過檢測的問題進行整理和匯總,并生成相應(yīng)的報告。報告可以包括問題的描述、嚴(yán)重程度、相關(guān)頁面URL等信息。然后,報告可以被發(fā)送給相關(guān)的利益相關(guān)者,例如開發(fā)或運營。

3.2 巡檢器

基于以上三個基類,根據(jù)不同巡檢場景開發(fā)不同的巡檢器(inspector),每一個巡檢器都包含了分別繼承以上三個基類的三個子類,繼承了基類的子類巡檢器通過覆寫/拓展基類方法以實現(xiàn)自己的個性化需求,以下是一個極簡的巡檢器例子:

// data-provider.ts
export class DataProvider extends DataProviderBase {
  // 實現(xiàn)特定的頁面列表獲取邏輯
  async fetchData(args) {
    return await axios.get('https://xxx.xxx').then(res => res.data.urlList)
  }
  // 每隔15分鐘獲取一次待檢測列表
  async schedule() {
    return [{cron: '*/15 * * * *',args: {}}]
  }
}


// page-inspector.ts
export class PageInspector extends PageInspectorBase {
  async onPageOpen(page, reporter: PageReporter, data) {
    const pageTitle = await page.evaluate('window.document.title')
    console.log('這里可以獲取到頁面title', pageTitle)
  }
}


// data-reporter.ts
export class DataReporter extends DataReporterBase {
  async beforeFeishuNotify(data: InspectorReportBase) {
    console.log('在飛書通知前做點什么', data)
    return data
  }
}

3.3 巡檢主程序

在巡檢系統(tǒng)中,每個頁面的檢測任務(wù)都是獨立的異步任務(wù),并且每份檢測報告的整理和發(fā)送也是獨立的異步任務(wù)。為了方便管理和維護這些異步任務(wù)以及任務(wù)消息的存儲和傳遞,巡檢系統(tǒng)使用Redis結(jié)合Bull作為巡檢系統(tǒng)的異步任務(wù)管理工具。

Redis是一個內(nèi)存數(shù)據(jù)庫,它提供高性能的數(shù)據(jù)存儲和訪問能力。

Bull是一個基于Redis的任務(wù)隊列庫,它提供了任務(wù)的調(diào)度、執(zhí)行和消息傳遞的功能。

有了巡檢器和異步任務(wù)管理能力,主程序的主要工作如下:

  1. 定義任務(wù):使用Bull創(chuàng)建兩個任務(wù)隊列,page_queue用于存放“頁面檢測任務(wù)”,reporter_queue用于存放“報告生成任務(wù)”。
  2. 生產(chǎn)任務(wù):在巡檢系統(tǒng)中,頁面檢測任務(wù)和報告生成任務(wù)的生產(chǎn)者(主程序)負(fù)責(zé)將任務(wù)添加到相應(yīng)的隊列中。當(dāng)巡檢器(inspector)需要進行頁面檢測時,生產(chǎn)者將頁面檢測任務(wù)加入page_queue;當(dāng)需要生成報告時,生產(chǎn)者將報告生成任務(wù)加入reporter_queue。
  3. 消費任務(wù):巡檢系統(tǒng)中的任務(wù)消費者(主程序)負(fù)責(zé)從任務(wù)隊列中獲取任務(wù)并執(zhí)行,一次檢測任務(wù)會有>=1個頁面檢測任務(wù),交由上文介紹的頁面檢查器PageInspector執(zhí)行頁面檢查,然后將檢測報告存儲到Redis中,當(dāng)該次檢測任務(wù)的所有頁面都完成檢測后,reporter_queue任務(wù)被創(chuàng)建并交由巡檢器(inspector)的DataReporter消費。

四、卡口服務(wù)

介紹完巡檢系統(tǒng),接下來我們看如何將卡口服務(wù)集成自巡檢系統(tǒng)中。

卡口服務(wù)的主要功能用一句話概括:接入巡檢系統(tǒng)的現(xiàn)有架構(gòu),對外暴露一個遠(yuǎn)程接口,提供給接口調(diào)用方主動檢測頁面的能力,然后將檢測報告回傳給調(diào)用方。

對比現(xiàn)有巡檢系統(tǒng)與卡口服務(wù)的差異:


檢測發(fā)起方

檢測case

檢測報告重點

檢測回調(diào)

在線報告

巡檢系統(tǒng)

系統(tǒng)自行定時觸發(fā)

通用檢測

重點關(guān)注異常

卡口服務(wù)

接口調(diào)用觸發(fā)

基于通用檢測拓展

給出詳細(xì)報告

根據(jù)需求觸發(fā)

從上文的巡檢系統(tǒng)架構(gòu)介紹以及分析上面的表格可知,卡口服務(wù)的開發(fā)工作就是基于巡檢系統(tǒng)的巡檢器架構(gòu)去定制實現(xiàn)一個巡檢器。

4.1 卡口服務(wù)運行時序

開始開發(fā)卡口服務(wù)的巡檢器之前,我們先梳理一下整個卡口服務(wù)的運行時序:

圖片

其中卡口服務(wù)主要開發(fā)任務(wù):步驟2、3、4、7。

4.2 創(chuàng)建任務(wù)接口

我們在上文提到,巡檢是一種后置檢測手段,所以巡檢系統(tǒng)的DataProviderBase(數(shù)據(jù)提供基類)主要能力是:“定時輪詢接收外部提供的待檢測頁面列表”。

對于卡口服務(wù)來說,檢測任務(wù)由檢測方主動創(chuàng)建,所以我們不需要過多關(guān)注DataProviderBase的實現(xiàn),而是要啟動一個api服務(wù),負(fù)責(zé)創(chuàng)建檢測任務(wù),示例代碼如下:

app.post('/xxx.xxx', async (req, res) => {
  const urls = req.body?.urls // 待檢測url列表
  const callBack = req.body?.callBack // 調(diào)用方接收報告的回調(diào)接口地址
  const transData = req.body?.transData // 調(diào)用方需要在回調(diào)中拿到的透傳數(shù)據(jù)
  // 巡檢系統(tǒng)檢測任務(wù)創(chuàng)建函數(shù)
  newApp.createJob(urls.map(url => ({ url,
      // 在redis任務(wù)隊列中傳遞的信息
      pos: { callBack, transData },
    })),
    jobId => { // 返回任務(wù)id給調(diào)用方
      res.json({ taskId: jobId })
    }
  )
})

4.3 頁面檢測

PageInspectorBase(頁面檢查器基類)是卡口服務(wù)的改造重點,在這個基類的子類實現(xiàn)方面,我們需要去做前文提到的具體待實現(xiàn)的檢測case,主要有兩類檢測case:

  1. 請求資源型檢測case:在子類中覆寫onResponse方法,針對不同的資源類型執(zhí)行不同的檢測邏輯;
  2. 運行時檢測case:在子類中覆寫onPageOpen方法,通過基類傳入的Page對象,注入js腳本,執(zhí)行頁面運行時檢測;
// 頁面檢測類
class PageInspector extends PageInspectorBase {
  // ...
  // 針對不同資源類型檢測方法配置Map
  checkResponseMethodsMap = new Map([['image', this.checkImageResponse]])
  
  // 請求資源型檢測入口 針對請求資源進行檢測
  async onResponse(response: Response, reporter: PageReporter, data: IJobItem) {
    const resourceType = response.request().resourceType()
    const checkMethod = this.checkResponseMethodsMap.get(resourceType)
    await checkMethod(response, reporter, data)
  }
  
  // 檢測圖片資源
  async checkImageResponse(response: Response, reporter: PageReporter, data: IJobItem) {
    // ...
    if (imageCdnList.includes(url)) {reporter.add({ errorType: "圖片類型錯誤.非cdn資源" })}
    // ...
  }
    
  // 運行時檢測入口 在頁面打開時執(zhí)行注入的js腳本進行運行時檢測
  async onPageOpen(page, reporter: PageReporter, data) {
    // ...
    const htmlText = await page.evaluate('window.document.documentElement.innerHTML')
    const phoneRegex = /\b((?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[35678]\d{2}|4(?:0\d|1[0-2]|9\d))|9[189]\d{2}|66\d{2})\d{6})\b/g;
    let phoneMatch: RegExpExecArray
    let collectMessage = []
    while ((phoneMatch = phoneRegex.exec(html)) !== null) {
      const phone = phoneMatch[1];collectMessage.push(`手機號碼:${phone}`);
    }
    collectMessage.forEach(val => {reporter.add({ errorMessage: `敏感信息:${val}`})})
    // ...
  }
  // ...
}

RegExp.prototype.exec()

在設(shè)置了 global 或 sticky 標(biāo)志位的情況下(如 /foo/g 或 /foo/y),JavaScript RegExp 對象是有狀態(tài)的。它們會將上次成功匹配后的位置記錄在 lastIndex 屬性中。使用此特性,exec() 可用來對單個字符串中的多次匹配結(jié)果進行逐條的遍歷(包括捕獲到的匹配),而相比之下, String.prototype.match() 只會返回匹配到的結(jié)果。

4.4 報告與回調(diào)

檢測任務(wù)執(zhí)行完畢后,reporter_queue中會被創(chuàng)建一個新的“報告生成任務(wù)”,主程序調(diào)用繼承了DataReporterBase的子類進行以下操作:

  1. 對檢測項逐一整理,將搜集到的錯誤進行等級分類,整理出報告源數(shù)據(jù);
  2. 根據(jù)報告源數(shù)據(jù)結(jié)合ejs模板生成靜態(tài)html并上傳,得到在線檢測報告地址;
  3. 向調(diào)用方回調(diào)檢測報告。

4.4.1 利用ChatGPT生成報告模板

大部分研發(fā)的UI設(shè)計水平有目共睹,與其死磕報告模板的樣式和交互,不如交給AI去搞定,輸入預(yù)先定義好的數(shù)據(jù)結(jié)構(gòu)和要求,ChatGPT能非??焖俚亟o到一個模板,然后只需要稍微做一點點調(diào)整就能達(dá)到可用的狀態(tài)。

Q: 我需要你寫一個ejs模板,這個模板用來展示一個統(tǒng)計報告,為了樣式和交互方便,模板會通過內(nèi)置bootstrap的css樣式和Jquery,你可以用到他們來實現(xiàn)html元素的組合和設(shè)置交互,具體的數(shù)據(jù)結(jié)構(gòu)如下:


interface CheckResult {
  name: string;
  status: 0 | 1;
  message: string;
  severityLevel: 0 | 1;
}


interface DetectionResult {
  url: string;
  status: 0 | 1;
  checkResults: CheckResult[];
}


interface InspectorReport {
  taskId: string;
  reporterUrl?: string;
  detectionResults: DetectionResult[];
  startTimeStr: string;
  endTimeStr: string;
  duration: number;
  pageTotal: number;
  taskStat: {
    completed: number,
    waiting: number,
    active: number,
    delayed: number,
    paused: number,
    failed: number,
  }
}


export interface InspectorReportBase {
  manifest: IManifest,
  data: InspectorReport;
}


export interface IManifest {
  name: string
  desc?: string
  notifyTo?: string[]
}
A: 好的,以下是基于提供的數(shù)據(jù)結(jié)構(gòu)設(shè)計的ejs模板:
<!DOCTYPE html>
<html lang="en">


<head>
  <meta charset="UTF-8">
  <link  rel="stylesheet">
  <script src="https://xxx.xxx.js"></script>
  <title>
    <%=data.manifest.desc%>
  </title>
</head>


<body>
  <div class="container">
    <h2 class="text-center">
      <%= data.manifest.desc %> 統(tǒng)計報告
    </h2>


    <div class="row">
      <div class="col-md-4">
        <div class="card">
          <div class="card-body">
            <h5 class="card-title">任務(wù)信息</h5>
            <p class="card-text">任務(wù)ID: <%= data.data.taskId %>
            </p>
            <p class="card-text">檢測開始時間: <%= data.data.startTimeStr %>
            </p>
            <p class="card-text">檢測結(jié)束時間: <%= data.data.endTimeStr %>
            </p>
            <p class="card-text">檢測時長: <%= data.data.duration %> 秒</p>
            <p class="card-text">檢測頁面數(shù): <%= data.data.pageTotal %>
            </p>
            <!--以下省略 -->
</body>
</html>

AI生成的在線報告模板:

圖片

4.4.2 與調(diào)用方解耦

作為服務(wù)提供者,卡口服務(wù)并不想過多關(guān)注調(diào)用者是誰,那么要如何實現(xiàn)與調(diào)用方的解耦?

——回顧上文“創(chuàng)建任務(wù)接口”環(huán)節(jié),這個接口設(shè)計的入?yún)⒂衏allBack和transData字段:

  1. callBack:檢測任務(wù)結(jié)束時,卡口服務(wù)將調(diào)用該地址回傳檢測報告;
  2. transData:檢測任務(wù)結(jié)束時,需要透傳給callBack的數(shù)據(jù);

頁面檢測任務(wù)完成后,在回調(diào)測試報告環(huán)節(jié),卡口服務(wù)將從redis隊列任務(wù)的緩存中中取出這兩個值,使用POST請求將報告和transData發(fā)送給callBack。

// 卡口服務(wù)回調(diào)示例代碼
axios.post(callBack, { 
  data: { msg: "本次檢測檢測報告如下:xxxxx", transData: `透傳的數(shù)據(jù)如下:${transData}` }
})

在后續(xù)的規(guī)劃中,為了使卡口服務(wù)能適應(yīng)更多場景的不同需求,參考后端微服務(wù)注冊中心的概念,可以實現(xiàn)一個簡易的注冊中心的抽象模型,進一步解耦卡口服務(wù)與其調(diào)用方之間的邏輯,同時能拓展更多功能:自定義檢測項、自定義報告模板等。

圖片

5、總結(jié)

對于卡口服務(wù)來說,學(xué)習(xí)和閱讀巡檢的源碼是一個重要的前置工作。通過深入理解巡檢系統(tǒng)的實現(xiàn)細(xì)節(jié)和底層架構(gòu)設(shè)計可以更好地理解巡檢系統(tǒng)是如何工作的,從而更好地進行定制和擴展,這些經(jīng)驗也幫助提升了自己的編碼能力和設(shè)計能力,在后續(xù)的技術(shù)項目中可以得到應(yīng)用和實踐。希望閱讀完本文的開發(fā)同學(xué)都能從本篇實踐總結(jié)中有所收獲~

引用/參考鏈接

GitHub - OptimalBits/bull

RegExp.prototype.exec() - JavaScript | MDN

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

2022-08-15 22:28:57

串口訪問鴻蒙

2022-06-27 09:36:29

攜程度假GraphQL多端開發(fā)

2017-09-01 18:27:36

前端 RxJs數(shù)據(jù)層

2018-04-20 10:38:25

2022-05-26 21:33:09

業(yè)務(wù)前端測試

2021-02-20 10:26:00

前端

2025-06-20 02:11:00

2019-10-15 09:20:40

Linux系統(tǒng)服務(wù)器

2022-05-26 10:12:21

前端優(yōu)化測試

2022-07-27 22:56:45

前端應(yīng)用緩存qiankun

2024-08-20 09:59:22

2023-09-27 07:28:02

CQRS架構(gòu)直播房間

2021-07-28 10:55:26

接口服務(wù)https:

2021-11-22 10:40:35

Linux腳本內(nèi)存

2021-04-15 08:08:48

微前端Web開發(fā)

2015-07-22 15:19:46

Docker云計算微服務(wù)

2025-02-13 00:00:12

LangServeDeepsee大模型

2017-05-09 12:40:05

2024-01-15 07:36:46

AI系統(tǒng)監(jiān)控系統(tǒng)

2022-06-20 06:24:13

5GWeb前端開發(fā)
點贊
收藏

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