您好,登錄后才能下訂單哦!
Serverless和SSR的示例分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
SSR 顧名思義就是 Server-Side Render
, 即服務端渲染。原理很簡單,就是服務端直接渲染出 HTML 字符串模板,瀏覽器可以直接解析該字符串模版顯示頁面,因此首屏的內容不再依賴 Javascript 的渲染(CSR - 客戶端渲染)。
SSR 的核心優勢:
首屏加載時間:因為是 HTML 直出,瀏覽器可以直接解析該字符串模版顯示頁面。
SEO 友好:正是因為服務端渲染輸出到瀏覽器的是完備的 html 字符串,使得搜索引擎 能抓取到真實的內容,利于 SEO。
SSR 需要注意的問題:
雖然 SSR 能快速呈現頁面,但是在 UI 框架(比如 React)加載成功之前,頁面是沒法進行 UI 交互的。
TTFB (Time To First Byte),即第一字節時間會變長,因為 SSR 相對于 CSR 需要在服務端渲染出更對的 HTML 片段,因此加載時間會變長。
更多的服務器端負載。由于 SSR 需要依賴 Node.js 服務渲染頁面,顯然會比僅僅提供靜態文件的 CSR 應用需要占用更多服務器 CPU 資源。以 React 為例,它的 renderToString()
方法是同步 CPU 綁定調用,這就意味著在它完成之前,服務器是無法處理其他請求的。因此在高并發場景,需要準備相應的服務器負載,并且做好緩存策略。
Serverless,它是云計算發展過程中出現的一種計算資源的抽象,依賴第三方服務,開發者可以更加專注的開發自己的業務代碼,而無需關心底層資源的分配、擴容和部署。
特點:
開發者只需要專注于業務,無需關心底層資源的分配、擴容和部署
按需使用和收費
自動擴縮容
更詳細的有關 Serverless 介紹,推薦閱讀:精讀《Serverless 給前端帶來了什么》
結合 Serverless 和 SSR 的特點,我們可以發現他們簡直是天作之合。借助 Serverless,前端團隊無需關注 SSR 服務器的部署、運維和擴容,可以極大地減少部署運維成本,更好的聚焦業務開發,提高開發效率。
同時也無需關心 SSR 服務器的性能問題,理論上 Serverless 是可以無限擴容的(當然云廠商對于一般用戶是有擴容上限的)。
既然說 Serverless 對于 SSR 來說有天然的優勢,那么我們如何將 SSR 應用遷移到Serverless 架構上呢?
本文將以 Next.js 框架為例,帶大家快速體驗部署一個 Serverless SSR 應用。
借助 Serverless Framework 的 Nextjs 組件,基本可以實現無縫遷移到騰訊云云函數 SCF 上。
$ npm init next-app serverless-next $ cd serverless-next # 編譯靜態文件 $ npm run build
$ npm install serverless -g
org: orgDemo app: appDemo stage: dev component: nextjs name: nextjsDemo inputs: src: ./ functionName: nextjsDemo region: ap-guangzhou runtime: Nodejs10.15 exclude: - .env apigatewayConf: protocols: - https environment: release
部署時需要進行身份驗證,如您的賬號未 登錄
或 注冊
騰訊云,您可以直接通過 微信
掃描命令行中的二維碼進行授權登陸和注冊。當然你也可以直接在項目下面創建 .env
文件,配置騰訊云的 SecretId
和 SecretKey
。如下:
TENCENT_SECRET_ID=123 TENCENT_SECRET_KEY=123
執行部署命令:
$ serverless deploy
以下
serverless
命令全部簡寫為sls
.
部署成功后,直接訪問 API 網關生成的域名,這里是就可以了。
類似
https://service-xxx-xxx.gz.apigw.tencentcs.com/release/
這種鏈接。
如果你的項目是基于 Express.js 的自定義 Server,那么需要在項目根目錄新建 sls.js 入口文件,只需要將原來啟動 Node.js Server 的入口文件復制到 sls.js 中,然后進行少量改造就好,默認入口 sls.js
文件如下:
const express = require('express'); const next = require('next'); const app = next({ dev: false }); const handle = app.getRequestHandler(); // 將原來的服務邏輯放入到異步函數 `createServer()`中 async function createServer() { // 內部內容需要根據項目需求進行修改就好,基本是你的 `server.js` 的原代碼 await app.prepare(); const server = express(); server.all('*', (req, res) => { return handle(req, res); }); // 定義返回二進制文件類型 // 由于 Next.js 框架默認開啟 `gzip`,所以這里需要配合為 `['*/*']` // 如果項目關閉了 `gzip` 壓縮,那么對于圖片類文件,需要定制化配置,比如 `['image/jpeg', 'image/png']` server.binaryTypes = ['*/*']; return server; } // export 函數 createServer() module.exports = createServer;
添加入口文件后,重新執行部署命令 sls deploy
就 OK 了。
至此,我們已經成功將整個 Next.js 應用遷移到騰訊云的 Serverless 架構上了,但是這里有個問題,就是所有的靜態資源都部署到了云函數 SCF 中,這就導致我們每次頁面請求的同時,會產生很多靜態源請求,對于 SCF 來說同一時間并發會比較高,而且很容易造成冷啟動。而且大量靜態資源通過 SCF 輸出,然后經過 API 網關返回,會額外增加鏈路長度,也會導致靜態資源加載慢,無形中也會拖累網頁的加載速度。
云廠商一般會提供云對象存儲功能,騰訊云叫 COS(對象存儲),用它來存儲我們的靜態資源有天然的優勢。而且開始使用有 50GB!!!
的免費容量(用來存喜愛的高清電影也是不錯的吧~)。
要是在我們項目部署時,將靜態資源統一上傳到 COS,然后靜態頁面通過 SCF 渲染,這樣既支持了 SSR,也解決了靜態資源訪問問題。而且 COS 也支持 CDN 加速,這樣靜態資源優化就更加方便。
那么我們如何將靜態資源上傳到 COS 呢?
登錄 [騰訊云 COS 控制臺](https://console.cloud.tencent.com/cos5) -> 創建存儲桶 -> 獲取 COS 訪問鏈接 -> 構建 Next.js 項目 -> 點擊 COS 上傳按鈕 -> 選擇上傳文件 -> 開始上傳 -> 完成
配置 COS 組件 -> 構建 Next.js 項目 -> 執行部署 COS 組件命令 -> 完成
接下來我們一起學習下文藝青年是如何做的。
在項目下創建 COS 文件夾,創建 cos/serverless.yml
配置文件:
org: orgDemo app: appDemo stage: dev component: cos name: serverless-cos inputs: # src 配置成你的next項目構建的目標目錄 src: ../.next/static # 由于 next框架在訪問靜態文件會自動附加 _next 前綴,所以這里需要配置上傳 COS 的目標目錄為 /_next targetDir: /_next/static bucket: serverless-bucket region: ap-guangzhou protocol: https acl: permissions: public-read
根據 COS 訪問鏈接生成規則:
<protocol>://<bucket-name>-<appid>.cos.<region>.myqcloud.com
可以直接推斷出部署后的訪問 URL 為:https://serverless-bucket-1251556596.cos.ap-guangzhou.myqcloud.com
然后在項目更目錄新建 next.config.js
文件,配置 assetPrefix
為該鏈接:
const isProd = process.env.NODE_ENV === 'production'; module.exports = { assetPrefix: isProd ? 'https://serverless-bucket-1251556596.cos.ap-guangzhou.myqcloud.com' : '', };
注意:如果你是直接給該 COS 配置了 CDN 域名。
然后執行構建:
$ npm run build
然后部署命令新增部署到 cos 命令執行就好:
$ sls deploy --target=./cos && sls deploy
然后我們就可以耐心等待部署完成。
優化后項目整體部署流程圖如下:
起初雖然看起來步驟很多,但是項目配置一次后,之后部署,只需要執行構建和部署命令,就可以了。
依賴 Serverless Component, 雖然我們可以快速部署 SSR 應用。但是對于開發者來說,性能才是最重要的。那么 Serverless 方案的性能表現如何呢?
為了跟傳統的 SSR 服務做對比,我專門找了一臺 CVM (騰訊云服務器),然后部署相同的 Next.js 應用。分別進行壓測和性能分析。
壓測配置如下:
起始人數 | 每階段增加人數 | 每階段持續時間(s) | 最大人數 | 發包間隔時間(ms) | 超時時間(ms) |
---|---|---|---|---|---|
5 | 5 | 30 | 100 | 0 | 10000 |
本文壓測使用的是 騰訊 WeTest。
均使用 Chrome 瀏覽器
方案 | 配置 | TTFB | FCP | TTI |
---|---|---|---|---|
騰訊云 CVM | 2 核,4G 內存,10M 帶寬 | 50.12ms | 2.0s | 2.1s |
騰訊云 Serverless | 128M 內存 | 69.88ms | 2.0s | 2.2s |
方案 | 配置 | 最大響應時間 | P95 耗時 | P50 耗時 | 平均響應時間 |
---|---|---|---|---|---|
騰訊云 CVM | 2 核,4G 內存,10M 帶寬 | 8830ms | 298ms | 35ms | 71.05 ms |
騰訊云 Serverless | 128M 內存 | 1733ms | 103ms | 73ms | 76.78 ms |
方案 | 配置 | 平均 TPS |
---|---|---|
騰訊云 CVM | 2 核,4G 內存,10M 帶寬 | 727.09 /s |
騰訊云 Serverless | 128M 內存 | 675.59 /s |
直接上圖:
從單用戶訪問頁面性能表現來看 Serverless 方案略遜于服務器方案
,但是頁面性能指標是可以優化的。從壓測來看,雖然 Serverless 的 平均響應時間
略大于 CVM,但是 最大響應時間
和 P95耗時
均優于 CVM 很多,CVM 的最大響應時間甚至接近 Serverless 的 3倍
。而且當并發量逐漸增大時,CVM 的響應時間變化明顯,而且越來越大,而 Serverless 則表現平穩,除了極個別的冷啟動,基本能在 200ms
以內。
由此可以看出,隨著并發的增加,SSR 會導致服務器負荷越來越大,從而會加大服務器的響應時間;而 Serverless 由于具有自動擴縮的能力,所以相對比較平穩。
當然由于測試條件有限,可能會有考慮不夠全面的地方,但是從壓測圖形來看,是完全符合理論預期的。
但是從價格對比來看,接近配置的 Serverless 方案基本不怎么花錢,甚至很多時候,免費額度就已經可以滿足需求了,這里為了增加 Serverless 費用,估計調大了調用次數,內存大小,但是即便如此,服務器方案還是接近 Serverless 方案的 10 倍!!!!!。
看完上述內容,你們掌握Serverless和SSR的示例分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。