韩日午夜在线资源一区二区_成人AV综合在线网站_欧美亚洲日本国产黑白配_大臣们罚皇上带玉势上朝_全彩口工漫画无遮爱丽丝

首都青年網(wǎng) |
  • 手機客戶端
  • 微信
您的位置:首頁 > 頭條 > 正文
世界快訊:NodeJs 實踐之他說
來源: 2023-05-17 17:22:34
NodeJs 實踐之他說

作為前端,我們知道 node 在構(gòu)建方面是成功的,我們也聽說過全棧,那么 node 是否能應(yīng)用在企業(yè)級的后端?一起來看一下騰訊視頻的 NodeJs 改造。

Tip: 故事大概是 2018 年,主角楊浩,來源于:


(資料圖)

背景

騰訊視頻是一個內(nèi)容型的網(wǎng)頁。

在 2014 年以前使用的是 C++ 動態(tài)生成頁面。有兩個問題:

前端不太會維護 C++ 的那套東西C++ 定時生成網(wǎng)頁。有多少個視頻,它就會生成多少個網(wǎng)頁,然后推送到對應(yīng)的服務(wù)器中。如果更改了某個視頻的信息,得等到下次生成網(wǎng)頁才會更新

于是打算使用 NodeJs來對其進行改造。

第一只怪 - 打通 NodeJs

由于騰訊視頻是內(nèi)容型的網(wǎng)頁,當(dāng)時有 30% 的流量來自搜索引擎,所以需要更好的 SEO,于是選用 SSR(服務(wù)器渲染)。

Tip: Vue_SSR中也提到服務(wù)端渲染的優(yōu)勢:更快的首屏加載、更好的 SEO

NodeJs 扮演的角色如下:

請求經(jīng)過 cdn,經(jīng)過 nginx 通過負載均衡訪問 NodeJs 服務(wù),NodeJs 從各個后臺服務(wù)拉取數(shù)據(jù),渲染好了在返回給前端。

Tip:相當(dāng)于以前用 c++ 生成頁面,現(xiàn)在由 NodeJs 生成頁面。

打通 RPC 調(diào)用

rpc(作用類似 http 協(xié)議) 就是遠端資源調(diào)用,因為 node 需要從各個后臺服務(wù)拉取數(shù)據(jù)。這里涉及4個方面的事情:

負載均衡。node 和后臺服務(wù)之間有一層負載均衡,用的是一種類DNS負載均衡,所以得和負載均衡服務(wù)交互,拿到每次需要訪問服務(wù)器的ipMongo/mysql/redis(redis - 基于鍵值對的內(nèi)存數(shù)據(jù)庫) 存儲的打通。比較簡單,就是對應(yīng) npm 包的使用后臺私有協(xié)議。例如二進制的協(xié)議某場景下比http協(xié)議好一些監(jiān)控系統(tǒng)/日志系統(tǒng)

Tip: DNS除了能解析域名之外還具有負載均衡的功能

高并發(fā)下進程管理

node 是單線程,使用 cluster 模塊創(chuàng)建多個 Nodejs 進程,實現(xiàn)高并發(fā)和高可用性。但 cluster 還有點缺陷,做了以下幾點優(yōu)化:

心跳- master 定時給 cluster 發(fā)信息,如果有回復(fù)說明它還活著,否則就是僵死,就 kill 它內(nèi)存檢測- 監(jiān)控 cluster 內(nèi)存,如果內(nèi)存過高,可能就是內(nèi)存泄漏,也殺死它重啟- cluster kill 后,有的應(yīng)用可能不能用,就需要將其重啟

Tip:在 Node.js 中,cluster 模塊提供了一種簡單的方式來創(chuàng)建多個 Node.js 進程,以實現(xiàn)高并發(fā)和高可用性。通過集群模塊,開發(fā)者可以使用現(xiàn)有的單線程程序代碼,并將其自動拆分到多個子進程中執(zhí)行,從而充分利用 CPU 和內(nèi)存資源,提高應(yīng)用的效率和穩(wěn)定性。

第二只怪 - 維護 NodeJs

終于把 Node 打通了,現(xiàn)在可以用 node 寫點東西了。

要用 node 寫一個穩(wěn)定的服務(wù),也不是那么簡單。node 很容易掛掉,比如一點語法問題。

Node 人員不足

懂前端的人很多,但懂 node 的就相對要少。寫后端需要懂后端那套東西,要會服務(wù)器調(diào)優(yōu),還要懂運維。

為了解決 Node 人員不足,決定使用框架來平滑 node 曲線。

之前要用 node 寫項目難度大,是因為需要經(jīng)歷這4步:業(yè)務(wù)邏輯 -> 會寫 NodeJs -> 熟悉 rpc 調(diào)用 -> 熟悉運維(性能調(diào)優(yōu))

現(xiàn)在用框架,只需要寫業(yè)務(wù)邏輯就能開干。

這里框架主要使用配置化,屏蔽底層復(fù)雜的實現(xiàn),對外暴露友好的配置。就像 webpack,讓前端構(gòu)建生態(tài)非常繁榮。

要做配置化,就得分析 ssr 本質(zhì):從各個后臺領(lǐng)取數(shù)據(jù),簡單處理后進行渲染。

ssr抽象表示:請求參數(shù) -> 后端數(shù)據(jù) + 模板 -> 頁面文本

ssr 公式:內(nèi)容=f(數(shù)據(jù)源,模板)

只要將數(shù)據(jù)源模板配置化,就可以通過一個函數(shù)解決 ssr 的問題。

模板引擎的選型

研究了如下幾種模板:

art-template 國內(nèi)有名的開源模板引擎es6 template string + vm.runInNewContext(編譯和運行代碼,作用類似 new Function("console.log("1")"))vue ssr、react ssr

art-template 中的 forEach 可以使用預(yù)編譯語法來實現(xiàn),由于交互較少,所以無需使用 vue和react。而且 es6 模板速度測試比 vue-server-render 快很多。

所以最終選取第二種方案:es6 template。

數(shù)據(jù)源

數(shù)據(jù)源的配置用如下一個 json 表示:

module.exports = {    video: {        url: "http://...."    },    vidviewcount: {        dependencies: ["video"],        url: "protobuf://union.video.qq.com/...."    },    rank: {        url: "redis://admin:admin@135246:65535/get?key=haha"    }}

這個 json 表示 ssr 過程中數(shù)據(jù)獲取邏輯,其中 vidviewcount 通過 dependencies字段指明依賴 video。

這里用 http、protobuf、redis三種協(xié)議(方式)獲取數(shù)據(jù)。一個協(xié)議對應(yīng)一個請求器,不在框架中的協(xié)議可以注冊即可。就像這樣:

factory.registerRequestor("http", requestor);function requestor(){    ...}

為了增加配置的靈活性,這里增加了幾個 hook:

{    ...    fixBefore: function(param){        // 檢測參數(shù)合法性        return param    },    fixAfter: function(data){        // 檢測返回數(shù)據(jù)合法性        if(!data.vid){            throw Error("xxx")        }        return data    },    onError: function(e){        return err;    }}
寫配置就是寫 SSR 邏輯

只要學(xué)會寫配置就能搞定 ssr 邏輯。

公式:內(nèi)容=f(數(shù)據(jù)源,模板)(參數(shù))

ssr 外部用 koa(nodejs 的web框架) 封裝一下就是一個服務(wù):

let app = koa()let ssr = pigfarm(data, template)app.use(async ctx => {    ctx.body = await ssr(ctx.query)})
第三只怪 - 搶后端飯碗的問題

后臺有后臺擅長的地方(邏輯、計算密集),前端有前端擅長的地方(前端網(wǎng)頁優(yōu)化)。

尋找一個合作共贏的方式。這里做了如下幾個有特色的前端服務(wù):

熱更新

每次業(yè)務(wù)邏輯的改動需要經(jīng)歷長時間的發(fā)布重啟

前面已經(jīng)將數(shù)據(jù)源模板做到了配置化,現(xiàn)在修改邏輯,只需要更改數(shù)據(jù)庫中的數(shù)據(jù)源和模板即可,做到熱更新。

首頁調(diào)優(yōu)

v.qq.com 首頁包含27個模塊

富含個性化內(nèi)容,無法緩存頁面龐大,速度慢全網(wǎng)頁超過40個rpc個性化接口調(diào)用慢

利用 transfer-encoding:chunked 快速返回首屏數(shù)據(jù),后面再加載2、3、4...屏的數(shù)據(jù)

Tip:BigPipe 是一個前端性能優(yōu)化技術(shù),采用分塊渲染的方式。transfer-encoding:chunked是一種 HTTP協(xié)議中定義的傳輸編碼方式之一。運行服務(wù)器在不知道響應(yīng)體大小的情況下,將響應(yīng)分成若干個固定大小的快進行傳輸。

容災(zāi)

前端容災(zāi)是指在前端應(yīng)用中,為了保障可靠性和穩(wěn)定性而采用的一系列技術(shù)和策略,以確保即使在系統(tǒng)出現(xiàn)部分異常或錯誤的情況下,仍然可以正常提供服務(wù)。比如網(wǎng)絡(luò)問題、服務(wù)器故障等

這里可以做整頁備份。

js 中用高階函數(shù)非常容易實現(xiàn)緩存。請看示例:

function memoize(func) {  // 用于緩存  const cache = {};  return function(...args) {    const key = JSON.stringify(args);    // 如果緩存中有值,直接返回    if (cache[key]) {      return cache[key];    }        const result = func.apply(this, args);    cache[key] = result;    return result;  };}

關(guān)鍵詞

圖片新聞
最近更新
Copyright @ 2008-2023 www.879606.com All Rights Reserved 首都青年網(wǎng) 版權(quán)所有
文章采集互聯(lián)網(wǎng),為了傳遞信息,如有出處與本站無關(guān)。 非本站原創(chuàng),系由網(wǎng)友自助上傳或轉(zhuǎn)載、采編于其它媒體,不代表本站的觀點和和看法,一切責(zé)任由發(fā)布者承擔(dān),與本站無關(guān)!
版權(quán)文章處理
聯(lián)系方式:QQ  39 60 29 14 2 @qq.com  備案號:皖I(lǐng)CP備2022009963號-20
霸州市| 巩留县| 湘阴县| 文山县| 永安市| 翁源县| 屏山县| 贡觉县| 衡阳县| 安国市| 甘谷县| 保靖县| 乐昌市| 越西县| 仁怀市| 河源市| 郯城县| 临沧市| 泊头市| 绩溪县| 武邑县| 青神县| 陆丰市| 乐亭县| 呼图壁县| 绥棱县| 福安市| 杭锦旗| 包头市| 鹿泉市| 石首市| 鲁山县| 华安县| 澳门| 遵化市| 九龙城区| 油尖旺区| 新源县| 临夏县| 砚山县| 南安市|