初次端內開發及node壓測優化

前段時間客戶端這邊作了一個爆款活動,我這邊支持了一下h5頁面,也是我作了這麼久的web頁面以後第一次嘗試作移動端和使用jsbridge,同時由於咱們的服務有使用nodejs踩了一些坑,在這裏記錄一下。css

端內開發代碼規範

這裏只記錄了幾個開發的時候沒有注意到的坑html

1. 無襯線字體

因爲一開始UI給的prd裏的字體不是瀏覽器自帶的字體,所以我這邊使用了默認字體,沒有特地的添加font-family屬性,後來在實際頁面中發現文字都變成了帶襯線的字體了,被UI提醒了一下才改爲了Helvetica字體。前端

而且iOS的字體庫和Android的字體庫不一樣,在Android下能夠正常訪問的字體可能由於在iOS中不存在而命中黑體,所以要在全局設置font-familynode

font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif;
複製代碼

2. 禁止用戶長按連接與圖片彈出菜單和選中文本

爲了爲了優化頁面體驗,咱們在頁面中應該禁止用戶長按連接和圖片彈出菜單的功能,以及禁用選中文本功能。web

a, img {
    -webkit-touch-callout: none; /* 禁止長按連接與圖片彈出菜單 */
}
html, body {
    -webkit-user-select: none;
    user-select: none;-webkit-touch-callout: none;
}
複製代碼

3. rem與dpr

這裏咱們使用的hotcss這個庫,一開始按照正常的rem開發去作,後來發現大小一直不對,最終從頭排查了一遍,發現是hotcss計算出的dpr是3而不是1,致使meta標籤最後是這個樣子的:chrome

<meta name="viewport" content="width=device-width, initial-scale=0.3333333333333333, minimum-scale=0.3333333333333333, maximum-scale=0.3333333333333333, user-scalable=no">
複製代碼

所以正常的計算出來的rem還要除3,如hotcss計算出的font-size67.5pxdpr1/3,則最終的單位應該爲$px/22.5 + remdocker

4. 性能優化

移動端的性能較web來講要差不少,所以要作不少的優化後端

  1. 圖片壓縮。壓縮圖片,儘量將圖片壓縮2-3次,能夠大幅減小圖片體積,加快頁面加載速度。圖片壓縮地址:tinypng.com/
  2. 儘量將經常使用數據離線化,儲存在localStorage中。
  3. 首屏請求數目儘量少,儘可能限制在4個之內,小圖片儘量使用精靈圖。即便不能使用精靈圖也儘量壓縮圖片大小。
  4. 首屏以外的資源使用按需加載和懶加載。
  5. iOS點擊有300ms延遲,所以要禁止頁面縮放從而取消點擊延遲
  6. chrome瀏覽器有自動適配文字大小的機制,開發時若是遇到文字大小和設置的像素大小不一致時記得去掉文字自動適配大小功能。-webkit-text-size-adjust: none;
  7. 谷歌在線網站評測工具:developers.google.com/speed/pages…

壓力測試

node層具體功能:瀏覽器

  1. 服務端渲染頁面
  2. 轉發前端請求,本次活動頁面的代碼存放在主站的倉庫中,因爲主站的域名不在客戶端那邊的白名單中(不是主站的客戶端,另外一個產品),所以須要node進行一次請求轉發。

之前咱們作壓測都是對後端接口進行壓測,此次因爲使用了node進行SSR,而且node還有接口轉發,所以還須要對node進行壓力測試,這也是咱們團隊第一次對node進行壓測。緩存

指標:

  1. 測試接口的qps負載能力
  2. 測試返回結果500所佔的比例
  3. 測試接口響應時間
  4. 測試頁面502的比例

壓測優化

本次活動對node層的要求是:SSR接口承載10000qps,轉發請求接口承載100000qps。這兩個數字其實都是峯值qps,也就是活動結束開獎那一刻的qps,平時qps很低,估計不到100。雖然感受QA同窗對峯值qps的估值也有點離譜,可是既然定了這個目標,咱們就須要努力達成。

1. pm2開啓cluster模式

因爲咱們申請的實例是雙核的CPU,所以首先想到的是使用pm2的cluster模式充分利用多核機器的優點。

踩坑:pm2裏面有一個參數是-i,表示要開啓的進程數量,通常是開啓和CPU數量相同的進程數量。-i max的意思是開啓和當前核心數目相同的進程數目。天真的我就這麼幹了,後來發現咱們的docker是運行在物理機上面的,物理機有60+的核心,使用max以後,pm2直接去讀取物理機的核心數目並開啓進程……一下就開了60多個進程,而後服務就崩潰了。

2. 請求緩存和打散

因爲後端機器數量不足,沒法承載10wqps,所以須要前端這邊作一些打散和緩存的策略。

  • 打散請求。開獎瞬間的請求並非同時併發發送到後端的,前端這邊使用隨機數,將全部請求在10s內打散。
  • 適當失敗。並非全部請求都須要成功,前端只須要將適當數量的請求發送給後端,其餘請求直接返回訪問失敗請稍後重試的提示就能夠了。一般秒殺活動中常常採用此策略,倒計時結束以後全部的用戶請求,只有十分之一能夠真正到達後端,大部分都在前端就被拒絕了。
  • 緩存請求結果。一些開獎活動的結果並非因人而異,而是你們看到的都同樣的,好比錦鯉活動,數千萬人蔘加,最後只有一人中獎,中獎信息全部人看到的都同樣。這種狀況下就適合使用node緩存策略。當node的接口拿到中獎信息以後,就將該請求的結果存到node的內存中,此後全部的用戶請求,node直接讀取內存中的數據來返回,不用真的發送給後端去等待響應。這樣基本上後端就沒有什麼壓力了,大部分工做node層就作完了,不過這樣也就意味着後端的壓力都轉移到了node這邊。

3. 緩存SSR

活動頁面一開始要求儘量快,所以咱們這邊直接採用了服務端渲染,後來壓測的時候發現,因爲開啓了SSR,一臺實例可以承載的qps從3000直接下降到200,可是又不能不使用ssr,由於國外一些地區網速可能會很慢,若是純粹使用客戶端渲染的話,可能頁面的加載時間會很長。

所以只能在ssr部分進行優化。

咱們第一時間想到的仍是利用內存,由於qps很高的時候基本集中在開獎的瞬間,而且這個瞬間的頁面是固定的,所以能夠直接在node中緩存開獎頁面的html字符串。

當第一個用戶拿到中獎信息以後,node緩存該次請求生成的html字符串,此後全部的請求都直接從內存中拿這個字符串使用就能夠了。

開獎以前的頁面本來是不打算作優化的,由於每一個用戶的信息都不同,若是放到內存那種的話可能會形成內存泄露,可是又怕有站內的大V宣傳次活動致使qps忽然增高,若是由於這種緣由致使服務器宕機的話就有點丟人了,因此最後仍是絕對對開獎以前的活動頁面也作一下緩存。

因爲頁面關於用戶信息的部分只有用戶名和倒計時剩餘時間的不一樣,所以咱們在node中緩存一個沒有用戶名和倒計時時間的公共字符串,而後請求到數據以後使用正則,將模板字符串中的用戶名和倒計時的佔位符替換掉便可。

4. 加機器

性能不夠,機器來湊。

上面說了那麼多,都沒有加機器管用。

咱們爲了支持活動,將4臺實例擴容到了150臺。用戶儘管訪問,能宕機算我輸。

相關文章
相關標籤/搜索