怎麼就敢用NodeJS寫千萬級別的服務後端

語言: CN / TW / HK
ead>

theme: scrolls-light

攜手創作,共同成長!這是我參與「掘金日新計劃 · 8 月更文挑戰」的第1天,點選檢視活動詳情 >>


前言:NodeJS真的是玩具嗎?真有人敢用這個玩具來寫後端服務,它能支撐成一個千萬級別的使用者量級嗎?怎麼就帶著我的團隊稀裡糊塗把這事而且做成。這篇文章將分享這次專案的併發實踐經驗。

一、專案背景

老闆說:公司要搞戰略NPS,需要一套問卷系統。要能配置問卷和回收答案就行,後端木有資源,給個機會前端搞全棧哈,先簡單搞哈,早期沒啥量,不用慌哈,看好你們喲。

image.png

寫個問卷系統,將它分成兩個部分就行。

image.png

  • 問卷配置管理端:不就是一個內部系統,公司內部人用,有啥量的,問題不大。(不在本文內容討論範圍)

  • 問卷服務:要給使用者訪問的呀,要做高併發呀。早期不是沒啥量嘛,先用NodeJS寫,等併發起來後,如果搞不定再讓後端接鍋😄唄,再說業務能不能起來都很難說,(反正人和程式碼有一個能跑就行😂)

問卷系統 (2).png

難得有一個機會可以搞全棧而且還要一定的使用者體量,雖然很慌,但是,還是很有幹勁的呀😁

image.png

二、系統架構

有一個搞全棧的機會,雖然很慌,但是,還是很有幹勁的呀😁,消化老闆的大餅,是時候要開幹了。

image.png

設計一個架構圖,再找有經驗的後端大佬們過一下。

image.png

上圖黃色部分是配置問卷的管理的模組,右邊綠色部分問卷對外的服務模組,在整個架構全域性來看,需要支援併發的其實只有兩個模組:

  • GET 問卷頁面渲染模組
  • POST 答案上報模組

三、應對之策

按照問卷回收經驗來說,大概,10個問卷頁面瀏覽 > 才會有1答案上報 處理併發要命的是頁面讀介面,其次是答案上報的寫介面。併發處理開幹了。

image.png

3.1 頁面渲染併發處理

渲染運營配置的問卷頁面,併發量是整個toC流量最大的,最具有挑戰難度的。 接下來通過拆解整個介面的過程,然後使用多級快取策略和改進的CSR來解決併發難題。

image.png

3.1.1 渲染流程

渲染前,需要獲取到資料庫運營配置問卷的題目相關的資訊

NPS問卷系統全棧架構解析.drawio.png

  • pageData,每個問卷配置的內容不一樣,運營啥時候修改問卷也不知道,需要在資料庫拉去配置對應問卷ID的配置給到前端來渲染頁面;(頁面級別的資料,變更不可控

  • render是一個JS渲染庫,所有問卷都是一樣,只要不釋出版就不會更新,放到CDN來扛併發即可。(應用級別的資料,變更可控

image.png

3.1.2 頁面資料快取策略

pageData是頁面資料,雖然要實時來取,但是可以做適當的快取策略。拉去pageData讀介面採用了多級快取,流程如下:

  • 首次通過遠端呼叫取讀取內部管理的問卷配置資料;
  • 渲染頁面完成,寫入記憶體快取和Redis快取;
  • 下次渲染,先按照記憶體 > redies快取讀取,沒有再重複首次訪問邏輯。

image.png

通過設定多級快取,減少mysql的併發壓力和頁面加速😄

image.png

3.1.3 渲染模式

為了向併發妥協,沒有使用伺服器端渲染。

image.png

我們選擇了CSR。

image.png

但是,為了頁面效能更好,我們改進CSR模式,把本來要讀pageData介面和html框架頁面放到伺服器端合併起來。

`` typescript /** * html拼接方法 * @param pageData,問卷題目配置資料 * @param resouceInfo,前端資源版本控制,由服務端控制做長快取更新使用 */ function render(pageData,resouceInfo){ const html =<!DOCTYPE html> ${pageData.title || '問卷'}

`

return html } ```

改進的CSR模式,在不增加伺服器負載的情況下,減少了資料讀取過程,將getPageData介面和html合二為一。頁面在瀏覽器渲染,不用在請求後端介面獲取pageData,首屏渲染速度更快!!!

image.png

image.png

3.2 上報介面併發處理

問卷答案上報介面,雖然量只有上面渲染介面的1/10,但是它是個寫介面,從外網流量寫入是內部系統服務的(恐慌.jpg)。

未命名.drawio (1).png

藉助kafka解耦後,併發請求帶來可以向後借時間,這就解決寫入的瓶頸和系統負載。

  • 通過調節kafka訊息消費的速度,讓內部管理的也可以應對ToC的問卷答案上報流量的寫入操作。
  • 解決系統負載,原本三個序列任務的耗時重計算任務放在併發處理中,改到只留資料補齊和校驗任務,另位兩個放到消費資料再執行,達到向後借時間目的。

image.png

四、達到效果

總算開發完成了, 老闆說:給你們找到了一個業務來用,他們後天要投X千萬使用者,要走PUSH渠道,你們接一下。

啊!啊!啊!這?不是說早期沒啥量嗎?😢咋一上來就x千萬使用者呢?還是走PUSH渠道

image.png

最後線上效果如下: image.png

注:部署了4臺8G16核的容器主機。

image.png

五、總結

這次專案用到redis、kafka、mysql完成由雲平臺提供,就是買買買就行,隨著各種資料庫和中介軟體上雲交付,前端寫後端已經完全可行。而且像小程式雲這種成熟的FASS雲設施普及,把後端程式碼也可以寫到前端裡去寫也越來越多,前端人,已經不再是切圖仔了。

關注我,帶你看點不一樣前端領域。

前端兩小時入門後端:

《前端入門後端只隔著一層HTTP協議》