簡體   English   中英

Node.js Express 服務器:使用 Node.js 線程池運行 res.render() / ejs.render()

[英]Node.js Express server: running res.render() / ejs.render() using Node.js threadpool

我們有一個應用程序,它使用 EJS 模板將服務器端渲染用於 SEO 目的。

我精通 Node.js,並且知道可能可以利用 Node.js 線程池進行異步 I/O,無論出於何種目的,無論是好主意還是壞主意。 目前我想知道是否可以使用線程池中的線程而不是 Node.js 中的主線程運行 ejs.render() 或 res.render()?

我們正在渲染函數中進行大量繁重的計算提升,我們肯定希望它脫離主線程,否則我們將為更多服務器支付 $$$。

只是渲染與您有關嗎? 還有其他模板引擎應該會產生更好的結果; 由於模板渲染應該是冪等操作,因此您可以另外分布在集群中。

V8 會將您的代碼編譯為匯編,如果您沒有遇到任何反優化或被垃圾收集器拖延,我相信您應該在您的網絡 I/O 限制附近。 我肯定會建議您嘗試其他模板引擎,在前端添加緩存 HTTP 反向代理並先運行一些基准測試。

眾所周知,EJS 是同步的,而且不會改變,所以基本上它是 Node.js 的低效渲染引擎,因為它在渲染視圖時阻塞 JS 線程,這會降低您的整體吞吐量,尤其是當您的渲染占用大量 CPU 時.

您絕對應該考慮其他一些選擇。 例如https://github.com/ericf/express-handlebars

如果您的網絡服務器中確實有大量 CPU 計算,那么無論如何 Node.js 絕對不是適合這項工作的工具。 有更好的服務器來處理多線程和並行處理。 您可以將 Node 設置為控制器,並將占用大量 CPU 的請求轉發到可以完成繁重工作的后端服務/服務器。

查看您在渲染期間正在執行的計算類型以提供更好的答案會很有幫助。

利用線程池(由libuv處理)可能是一個壞主意,但當然有可能..您只需要一些 C++ 技能和libuv庫的uv_queue_work()方法來安排工作人員的工作線。

我已經嘗試構建一個在分叉進程中運行的腳本引擎(在此處閱讀節點的子進程模塊)。 我發現這是實現渲染引擎的一個有吸引力的提議。 是的,存在傳遞參數(post/get 查詢字符串、會話狀態等)的問題,但它們很容易處理,特別是如果您使用 fork 選項(而不是 exec 或 spawn)。 有標准的消息傳遞方法可以在孩子和父母之間進行通信。

唯一的開銷是生成額外的節點實例(渲染引擎本身)。 如果您在腳本引擎中進行大量計算,那么與渲染所花費的時間相比,此常量與分叉新進程的每個渲染請求的一次性開銷將是較小的。

如果 EJS 渲染阻塞了主節點線程,那么如果您在渲染期間進行任何重要的計算,那么僅憑這一點就足夠了不要使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM