溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Serverless和SSR的示例分析

發(fā)布時(shí)間:2021-12-30 09:48:48 來源:億速云 閱讀:134 作者:柒染 欄目:云計(jì)算

Serverless和SSR的示例分析,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

什么是 SSR

SSR 顧名思義就是 Server-Side Render, 即服務(wù)端渲染。原理很簡單,就是服務(wù)端直接渲染出 HTML 字符串模板,瀏覽器可以直接解析該字符串模版顯示頁面,因此首屏的內(nèi)容不再依賴 Javascript 的渲染(CSR - 客戶端渲染)。

SSR 的核心優(yōu)勢(shì):

  1. 首屏加載時(shí)間:因?yàn)槭?HTML 直出,瀏覽器可以直接解析該字符串模版顯示頁面。

  2. SEO 友好:正是因?yàn)榉?wù)端渲染輸出到瀏覽器的是完備的 html 字符串,使得搜索引擎 能抓取到真實(shí)的內(nèi)容,利于 SEO。

SSR 需要注意的問題:

  1. 雖然 SSR 能快速呈現(xiàn)頁面,但是在 UI 框架(比如 React)加載成功之前,頁面是沒法進(jìn)行 UI 交互的。

  2. TTFB (Time To First Byte),即第一字節(jié)時(shí)間會(huì)變長,因?yàn)?SSR 相對(duì)于 CSR 需要在服務(wù)端渲染出更對(duì)的 HTML 片段,因此加載時(shí)間會(huì)變長。

  3. 更多的服務(wù)器端負(fù)載。由于 SSR 需要依賴 Node.js 服務(wù)渲染頁面,顯然會(huì)比僅僅提供靜態(tài)文件的 CSR 應(yīng)用需要占用更多服務(wù)器 CPU 資源。以 React 為例,它的 renderToString() 方法是同步 CPU 綁定調(diào)用,這就意味著在它完成之前,服務(wù)器是無法處理其他請(qǐng)求的。因此在高并發(fā)場景,需要準(zhǔn)備相應(yīng)的服務(wù)器負(fù)載,并且做好緩存策略。

什么是 Serverless

Serverless,它是云計(jì)算發(fā)展過程中出現(xiàn)的一種計(jì)算資源的抽象,依賴第三方服務(wù),開發(fā)者可以更加專注的開發(fā)自己的業(yè)務(wù)代碼,而無需關(guān)心底層資源的分配、擴(kuò)容和部署。

特點(diǎn):

  1. 開發(fā)者只需要專注于業(yè)務(wù),無需關(guān)心底層資源的分配、擴(kuò)容和部署

  2. 按需使用和收費(fèi)

  3. 自動(dòng)擴(kuò)縮容

更詳細(xì)的有關(guān) Serverless 介紹,推薦閱讀:精讀《Serverless 給前端帶來了什么》

Serverless + SSR

結(jié)合 Serverless 和 SSR 的特點(diǎn),我們可以發(fā)現(xiàn)他們簡直是天作之合。借助 Serverless,前端團(tuán)隊(duì)無需關(guān)注 SSR 服務(wù)器的部署、運(yùn)維和擴(kuò)容,可以極大地減少部署運(yùn)維成本,更好的聚焦業(yè)務(wù)開發(fā),提高開發(fā)效率。

同時(shí)也無需關(guān)心 SSR 服務(wù)器的性能問題,理論上 Serverless 是可以無限擴(kuò)容的(當(dāng)然云廠商對(duì)于一般用戶是有擴(kuò)容上限的)。

如何快速將 SSR 應(yīng)用 Serverless 化?

既然說 Serverless 對(duì)于 SSR 來說有天然的優(yōu)勢(shì),那么我們?nèi)绾螌?SSR 應(yīng)用遷移到Serverless 架構(gòu)上呢?

本文將以 Next.js 框架為例,帶大家快速體驗(yàn)部署一個(gè) Serverless SSR 應(yīng)用。

借助 Serverless Framework 的 Nextjs 組件,基本可以實(shí)現(xiàn)無縫遷移到騰訊云云函數(shù) SCF 上。

1. 初始化 Next.js 項(xiàng)目

$ npm init next-app serverless-next
$ cd serverless-next

# 編譯靜態(tài)文件
$ npm run build

2. 全局安裝 Serverless CLI

$ npm install serverless -g

3. 配置 severless.yml

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

4. 部署

部署時(shí)需要進(jìn)行身份驗(yàn)證,如您的賬號(hào)未 登錄注冊(cè) 騰訊云,您可以直接通過 微信 掃描命令行中的二維碼進(jìn)行授權(quán)登陸和注冊(cè)。當(dāng)然你也可以直接在項(xiàng)目下面創(chuàng)建 .env 文件,配置騰訊云的 SecretIdSecretKey。如下:

TENCENT_SECRET_ID=123
TENCENT_SECRET_KEY=123

執(zhí)行部署命令:

$ serverless deploy

以下 serverless 命令全部簡寫為 sls.

部署成功后,直接訪問 API 網(wǎng)關(guān)生成的域名,這里是就可以了。

類似 https://service-xxx-xxx.gz.apigw.tencentcs.com/release/ 這種鏈接。

現(xiàn)有 Next.js 應(yīng)用遷移

如果你的項(xiàng)目是基于 Express.js 的自定義 Server,那么需要在項(xiàng)目根目錄新建 sls.js 入口文件,只需要將原來啟動(dòng) Node.js Server 的入口文件復(fù)制到 sls.js 中,然后進(jìn)行少量改造就好,默認(rèn)入口 sls.js 文件如下:

const express = require('express');
const next = require('next');
const app = next({ dev: false });
const handle = app.getRequestHandler();

// 將原來的服務(wù)邏輯放入到異步函數(shù) `createServer()`中
async function createServer() {
  // 內(nèi)部內(nèi)容需要根據(jù)項(xiàng)目需求進(jìn)行修改就好,基本是你的 `server.js` 的原代碼
  await app.prepare();
  const server = express();

  server.all('*', (req, res) => {
    return handle(req, res);
  });

  // 定義返回二進(jìn)制文件類型
  // 由于 Next.js 框架默認(rèn)開啟 `gzip`,所以這里需要配合為 `['*/*']`
  // 如果項(xiàng)目關(guān)閉了 `gzip` 壓縮,那么對(duì)于圖片類文件,需要定制化配置,比如 `['image/jpeg', 'image/png']`
  server.binaryTypes = ['*/*'];

  return server;
}

// export 函數(shù) createServer()
module.exports = createServer;

添加入口文件后,重新執(zhí)行部署命令 sls deploy 就 OK 了。

Serverless 部署方案的優(yōu)化

至此,我們已經(jīng)成功將整個(gè) Next.js 應(yīng)用遷移到騰訊云的 Serverless 架構(gòu)上了,但是這里有個(gè)問題,就是所有的靜態(tài)資源都部署到了云函數(shù) SCF 中,這就導(dǎo)致我們每次頁面請(qǐng)求的同時(shí),會(huì)產(chǎn)生很多靜態(tài)源請(qǐng)求,對(duì)于 SCF 來說同一時(shí)間并發(fā)會(huì)比較高,而且很容易造成冷啟動(dòng)。而且大量靜態(tài)資源通過 SCF 輸出,然后經(jīng)過 API 網(wǎng)關(guān)返回,會(huì)額外增加鏈路長度,也會(huì)導(dǎo)致靜態(tài)資源加載慢,無形中也會(huì)拖累網(wǎng)頁的加載速度。

云廠商一般會(huì)提供云對(duì)象存儲(chǔ)功能,騰訊云叫 COS(對(duì)象存儲(chǔ)),用它來存儲(chǔ)我們的靜態(tài)資源有天然的優(yōu)勢(shì)。而且開始使用有 50GB!!! 的免費(fèi)容量(用來存喜愛的高清電影也是不錯(cuò)的吧~)。

要是在我們項(xiàng)目部署時(shí),將靜態(tài)資源統(tǒng)一上傳到 COS,然后靜態(tài)頁面通過 SCF 渲染,這樣既支持了 SSR,也解決了靜態(tài)資源訪問問題。而且 COS 也支持 CDN 加速,這樣靜態(tài)資源優(yōu)化就更加方便。

那么我們?nèi)绾螌㈧o態(tài)資源上傳到 COS 呢?

普通青年做法

登錄 [騰訊云 COS 控制臺(tái)](https://console.cloud.tencent.com/cos5) -> 創(chuàng)建存儲(chǔ)桶 -> 獲取 COS 訪問鏈接 -> 構(gòu)建 Next.js 項(xiàng)目 -> 點(diǎn)擊 COS 上傳按鈕 -> 選擇上傳文件 -> 開始上傳 -> 完成

文藝青年做法

配置 COS 組件 -> 構(gòu)建 Next.js 項(xiàng)目 -> 執(zhí)行部署 COS 組件命令 -> 完成

接下來我們一起學(xué)習(xí)下文藝青年是如何做的。

在項(xiàng)目下創(chuàng)建 COS 文件夾,創(chuàng)建 cos/serverless.yml 配置文件:

org: orgDemo
app: appDemo
stage: dev
component: cos
name: serverless-cos

inputs:
  # src 配置成你的next項(xiàng)目構(gòu)建的目標(biāo)目錄
  src: ../.next/static
  # 由于 next框架在訪問靜態(tài)文件會(huì)自動(dòng)附加 _next 前綴,所以這里需要配置上傳 COS 的目標(biāo)目錄為 /_next
  targetDir: /_next/static
  bucket: serverless-bucket
  region: ap-guangzhou
  protocol: https
  acl:
    permissions: public-read

根據(jù) COS 訪問鏈接生成規(guī)則:

<protocol>://<bucket-name>-<appid>.cos.<region>.myqcloud.com

可以直接推斷出部署后的訪問 URL 為:https://serverless-bucket-1251556596.cos.ap-guangzhou.myqcloud.com

然后在項(xiàng)目更目錄新建 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 域名。

然后執(zhí)行構(gòu)建:

$ npm run build

然后部署命令新增部署到 cos 命令執(zhí)行就好:

$ sls deploy --target=./cos && sls deploy

然后我們就可以耐心等待部署完成。

Serverless + Next.js 部署流程圖

優(yōu)化后項(xiàng)目整體部署流程圖如下:

Serverless和SSR的示例分析

起初雖然看起來步驟很多,但是項(xiàng)目配置一次后,之后部署,只需要執(zhí)行構(gòu)建和部署命令,就可以了。

性能分析

依賴 Serverless Component, 雖然我們可以快速部署 SSR 應(yīng)用。但是對(duì)于開發(fā)者來說,性能才是最重要的。那么 Serverless 方案的性能表現(xiàn)如何呢?

為了跟傳統(tǒng)的 SSR 服務(wù)做對(duì)比,我專門找了一臺(tái) CVM (騰訊云服務(wù)器),然后部署相同的 Next.js 應(yīng)用。分別進(jìn)行壓測(cè)和性能分析。

壓測(cè)配置如下:

起始人數(shù)每階段增加人數(shù)每階段持續(xù)時(shí)間(s)最大人數(shù)發(fā)包間隔時(shí)間(ms)超時(shí)時(shí)間(ms)
5530100010000

本文壓測(cè)使用的是 騰訊 WeTest。

頁面訪問性能對(duì)比

均使用 Chrome 瀏覽器

方案配置TTFBFCPTTI
騰訊云 CVM2 核,4G 內(nèi)存,10M 帶寬50.12ms2.0s2.1s
騰訊云 Serverless128M 內(nèi)存69.88ms2.0s2.2s

壓測(cè)性能對(duì)比

1.響應(yīng)時(shí)間:

Serverless和SSR的示例分析

Serverless和SSR的示例分析

方案配置最大響應(yīng)時(shí)間P95 耗時(shí)P50 耗時(shí)平均響應(yīng)時(shí)間
騰訊云 CVM2 核,4G 內(nèi)存,10M 帶寬8830ms298ms35ms71.05 ms
騰訊云 Serverless128M 內(nèi)存1733ms103ms73ms76.78 ms

2.TPS:

Serverless和SSR的示例分析

Serverless和SSR的示例分析

方案配置平均 TPS
騰訊云 CVM2 核,4G 內(nèi)存,10M 帶寬727.09 /s
騰訊云 Serverless128M 內(nèi)存675.59 /s

價(jià)格預(yù)算對(duì)比

直接上圖:

Serverless和SSR的示例分析

對(duì)比分析

從單用戶訪問頁面性能表現(xiàn)來看 Serverless 方案略遜于服務(wù)器方案,但是頁面性能指標(biāo)是可以優(yōu)化的。從壓測(cè)來看,雖然 Serverless 的 平均響應(yīng)時(shí)間 略大于 CVM,但是 最大響應(yīng)時(shí)間P95耗時(shí) 均優(yōu)于 CVM 很多,CVM 的最大響應(yīng)時(shí)間甚至接近 Serverless 的 3倍。而且當(dāng)并發(fā)量逐漸增大時(shí),CVM 的響應(yīng)時(shí)間變化明顯,而且越來越大,而 Serverless 則表現(xiàn)平穩(wěn),除了極個(gè)別的冷啟動(dòng),基本能在 200ms 以內(nèi)。

由此可以看出,隨著并發(fā)的增加,SSR 會(huì)導(dǎo)致服務(wù)器負(fù)荷越來越大,從而會(huì)加大服務(wù)器的響應(yīng)時(shí)間;而 Serverless 由于具有自動(dòng)擴(kuò)縮的能力,所以相對(duì)比較平穩(wěn)。

當(dāng)然由于測(cè)試條件有限,可能會(huì)有考慮不夠全面的地方,但是從壓測(cè)圖形來看,是完全符合理論預(yù)期的。

但是從價(jià)格對(duì)比來看,接近配置的 Serverless 方案基本不怎么花錢,甚至很多時(shí)候,免費(fèi)額度就已經(jīng)可以滿足需求了,這里為了增加 Serverless 費(fèi)用,估計(jì)調(diào)大了調(diào)用次數(shù),內(nèi)存大小,但是即便如此,服務(wù)器方案還是接近 Serverless 方案的 10 倍!!!!!。

看完上述內(nèi)容,你們掌握Serverless和SSR的示例分析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI