蘇寧的Node.js實踐:不低于Java的渲染性能、安全穩定迭代快

前端 Node.js 的使用場景大多集中在前端工具上,當前的前端主要把它定位為輔助。蘇寧易購使用 Node.js 作為前后端分離的主要手段,經歷了從技術引進到全面開花,從邊緣功能到核心業務,從紛亂到穩定的過程。同時 Node.js 作為新引入的技術,與公司原有架構融合銜接面臨著怎樣的挑戰?以下是蘇寧技術總監 禹立彬老師在 7 月深圳 ArchSummit 全球架構師峰會上的演講整理。

在蘇寧引入 Node.js 之前,蘇寧已經有了成熟的技術架構。

\"\"

蘇寧的技術架構,由蘇寧云、基礎支撐、后臺、中臺和前臺組成。蘇寧云主要為業務開發提供云服務。基礎支撐,包括數據連接協議、防火墻、日志、中間件、短信等。在蘇寧云和基礎支撐之上,業務開發分為前中后臺。而 Web 前端,主要集中在前臺上。包含 PC 端、移動 WAP 端等。

Node.js 的應用非常廣泛,在不同的公司,可以用作微服務,也可以用來提供 API,蘇寧引入 Node.js,最主要的,是用 Node.js 做中間層,當做一個 Web 渲染器,渲染頁面,來實現前后端分離。

Web 前臺系統

\"\"

在前臺系統里,以前的開發模式,完全是 Java 技術棧。Java 系統,分為 Java Service 服務器,和 Java Web 服務器,Java WEB 服務器讀取 Java Service 服務器提供的接口,通過 FTL 模板來渲染頁面。

\"\"

引入了 Node.js 以后,蘇寧研發團隊的目標是使用 Node.js 替代 Java Web 服務器的渲染位置,使用 Node 模板,去替換 Java 模板,去除了模板文件誰寫這樣的模糊地帶,讓后端的 Java 工程師,只寫 JSON 服務,實現前后端分離。

在應用前后端分離后,顯式的獲得了一些好處,Node.js 系統的迭代速度優勢明顯強于 Java Web,包括由于 Node.js 的輕量,帶來的快速開發快速迭代,以及減少了前后端溝通上的“聯調”時間成本,加快了項目的開發速度。同時,減少老項目里 Java 后臺工程師寫頁面導致的一些 BUG,提高了代碼質量。

由于以上的這些優點,現在蘇寧易購的 Node.js 項目越來越多,逐漸深入到核心業務。最早期,蘇寧只是在用戶體驗收集這樣的邊緣頁面使用 Node.js,現在已經在海外購,小程序,大聚惠,我的易購,香港站,購物車等業務中都廣泛的使用了 Node.js,這樣就不可避免的直面更多的技術挑戰。

Node.js 如何融入已有技術架構

當只是作為邊緣業務時,Node.js 項目尚可以通過一些臨時方案,或者引入試點,來逃避,但是深入核心業務后,Node.js 項目很快,就會被納入總的技術架構里。

\"\"

這是一張比較簡單的 Node.js 應用部署圖。一個 Node.js 應用被訪問時,會使用公共的負載均衡,使用應用防火墻,當達到 Node 服務器時,要使用物理機和虛擬機,Node 服務器要訪問 Java Service 服務器也需要連接協議

\"\"

最簡單的是 IaaS,在這個層級上,Node 可以完全可以復用蘇寧云成熟的網絡,存儲,物理機,虛擬機等資源。

\"\"

到了虛擬機這個層級,在這幅 Node.js 服務器圖上,可以看到單臺 Node 服務器,有一個 Nginx,來做訪問的 accessLog 和做反向代理到本機的 Node.js 應用端口,這臺機器上同時安裝了 PM2,來啟動多個 Node 應用,對應不同的端口,來提供對外服務。

\"\"

在 PaaS 這個層級上,蘇寧也盡量沿用了公司已有的技術資源。比如在操作系統方面,使用了 Linux,盡量向已有技術架構靠攏。

在服務器的 Node.js 版本上,在去年年初的版本是 Node 6.9,去年年底已經將 Node 版本升級到 Node 8 了,研發團隊堅持使用 LTS 版本的 Node.js。到 Node 有大版本更新時,同時更新 PaaS 平臺的 Node 版本。

在 Nginx 上,選擇的也是已有的通用 Nginx 版本,Node 服務器對 Nginx 版本要求不嚴格,Nginx 監聽多域名的 80 端口后,反向代理到 Node 端口就好。

Redis 的情況要麻煩一些,Node.js 由于進程的原因,遇到 Session 這樣需要多進程或者多服務器直接共享數據時,就必須借助 Redis。很顯然,Java 體系內,并沒有對應的 Node 版本的 Redis 客戶端,于是蘇寧自己編寫了一個基于 ioredis 的 Redis 客戶端,來滿足需求。

在 DB 上,蘇寧則遵循總的技術架構要求,Node 服務器不直連 DB,要獲取數據時,永遠是連接 Java 服務。

監控報警

解決了服務器環境后,Node 也要接入日志服務和報警系統。通過配置 Nginx 日志格式和 PM2 的日志插件 pm2-logrotate 來將日志格式符合總技術架構的日志平臺要求,并在日志平臺上配置 4XX 和 5XX 報警,并且針對 Node 本身的一些特色,編寫 PM2 插件,監控 Node 進程異常,并發送異常到蘇寧內部的即時通信團建上。

CI/CD 發布系統

服務器好了,代碼編寫好了,也需要發布。利用公司的統一發布平臺,在平臺上新建了 Node.js 標準發布,統一了 Node 代碼包打包方案,統一了代碼部署目錄,統一從內部私庫安裝 NPM 包,統一了應用重啟的方法。

\"\"

除此之外,為了滿足公司的總技術架構要求,蘇寧研發團隊還編寫了基于 Node 的調用鏈監控組件,可以適配 ESB/RSF 通信協議的客戶端組件,以及適合 Varnish 下的 KOA,EXPRESS 中間件。

技術挑戰

解決了技術架構要求方面的問題,Node 可以正規軍上崗了,核心業務又會帶來更高的技術要求。

以大聚惠頁面為例,大聚惠是蘇寧的一項營銷業務,很多優惠活動,是通過大聚惠的名義放出的,因此業務非常重要。又因為運營需要,總是在凌晨 0 點,貨品上新,要求此時頁面不能有緩存,而且由于電商業務的特殊性,會遇到 618,818,雙十一這種半夜搶購的情況,因此全靠服務器硬扛流量洪峰,這就對應用性能,提出了很高的要求。

這個項目上線的時候,恰好是升級了 Node 8,研發團隊把框架從 express 轉換為 KOA,寫了一樣的代碼,壓測時,4C4G 單機才 40TPS,而同樣的 Java 系統,單機約為 200TPS,性能差距明顯。

并發性能優化之路

首先考慮是緩存問題,經過排查,在 KOA 下,并不會默認開啟,模板緩存,導致每次總是去硬盤讀模板,當然快不了。果斷優化,TPS 上升為 120TPS,依然差距明顯。Express 框架中會默認開啟模板緩存,而默認的 KOA2 并不會開啟,首先開啟模板緩存性能提升明顯。

另外,通過 CPU-PROFILER 排查,發現路由消耗的時間挺多,匹配字符串路由,和匹配正則路由,時間消耗差距明顯,于是將路由排序,優先選擇字符串路由,將 TPS 推向 140TPS。

再查,為了減少并發,除渲染模板外,Node 還在業務里,合并了靜態資源地址,并且中間件加載的策略也可以優化,去除掉一些可以不用的中間件。比如只用 EJS 模板,那么就去除其他模板引擎的支持,通過這些優化,講 TPS 提升到了 180TPS。

TPS 沒有提升后,再排查,發現 include 函數執行時間很長,發現 ejs 源碼處理 include 時,總是去硬盤里查找是否有被 include 的模板文件,而這個頁面是多人開發,include 使用非常頻繁,再進一步優化,終于達到了 220TPS。

不低于 Java 的渲染性能

最后,獲得了不低于 Java 的渲染性能。很多文章博客對待 Node 渲染頁面時會兩級分化,一極認為 Node 不適合做這種 CPU 密集型操作,另一極就是不斷宣揚 Node 性能強勁,但是在蘇寧實際的應用中,從來沒想過超過 Java 多少倍的性能,事實上也是。Node 的基礎性能略高于或者持平于老的 Java FTL 渲染器。

安全與穩定

除了性能,安全與穩定也是重點需要的環節。針對 Node.js 來說,客觀的說,安全文檔方面是不如 Java 等語言的。

一方面是最后后來者,追趕前輩需要時間,另一方面也是 Node.js 的固有問題。Node.js 是單線程的,代碼報錯會導致進程退出,在 Node 生態早期,會直接導致 Node 訪問掛掉;

第二個,JS 是弱類型語言,很多人認為弱類型的語言寫的沒有安全感,沒有代碼檢查;

第三個,NPM 很好,開源社區很強大,組件很多很方便,但是對于企業用戶來說,都抵不過一個 left-pad 事件,公網的 NPM 包也會良莠不齊,如果出現了安全漏洞,影響就會非常大。

問題如何解決

NPM 包策略。蘇寧使用公司的私有 NPM 倉庫來安裝 NPM 包,避免外網擾動,導致無法安裝問題。在核心業務中,限制使用不流行的 NPM 包,減少風險。在 package.json 里的包版本,使用確定的版本,不用符號,減少包升級導致的 bug。對于自己開發的 NPM 包,嚴格進行單元測試及安全測試,進一步的減少風險。

使用 PM2。針對 Node 進程掛掉的問題,蘇寧使用了留下的 PM2,來保證 Node 進程的存活。當 Node 進程掛掉時,PM2 會重啟他們。感謝 PM2,通過它,也實現了發布的無縫重啟,保證了平滑升級。

Node.js 系統的相對安全

安全上,蘇寧強制了所有的 Node 系統加入應用防火墻 WAF,使用基于 KOA 的安全中間件 XSS,盡量使用精確匹配的路由,減少注入。并在上線前,做完全的安全測試,實現 Node 系統的相對安全。

前端團隊的挑戰

\"\"

另一方面,由于引入了 Node,前端工程師對 Node 相關的知識了解較少,也會犯一些低級錯誤,技術挑戰也是非常大的,知識要求被增加了很多。

為了解決這個問題,蘇寧成立了專門的前端架構組,為各業務團隊保駕護航。在發布,配置,安全監測等各個方面幫助業務開發團隊。

全棧技能提升計劃

\"\"

并在工作中,加強 Node 技能培訓。梳理出容易犯的低級錯誤,比如 promise 不寫 catch,某個條件分支里,不寫請求返回,通過宣講的方式,提高代碼質量,并組織代碼評審等活動,進一步的提升技術能力。

Node.js 的影響

可以說,進入了核心業務,前端團隊遇到的挑戰是越來越大的,同時,Node 的推進也帶來了一些正面負面的影響,時間有限,不做太多的講解,僅舉幾個方面。

第一個方面,項目更敏捷了,Node.js 發布不涉及后臺服務,即使發布出了小問題,也可以快速再次發布和回滾,因為 Node.js 系統其實是可以 24 小時發布,對業務支撐顯然更迅速敏捷。運營商務。都顯然的歡迎 Node。

同時,Node 的引入,也對前端團隊帶來了影響。Node 的引入帶來了前端工作量的增加,需要更多的前端工程師投入。

另一方面,也顯著的提高了團隊的技術活力,在團隊內部刮起了全棧風,技術更活躍,解決問題的方案也更多了。

最后還有一些小型的負面影響,定位 bug 時,時間有所增加。需要查 Node 的問題,還是 Java 的問題;另一方面,訪問性能因為 HTTP 的問題,略微增加了幾毫秒。當然這對于前面的好處來講都是可以接受的。

嘉賓介紹

禹立彬,蘇寧技術總監,十年 Web 前端開發經歷,中國最早一批前端開發者,歷任西祠胡同前端負責人,途牛旅游網前端架構師等職務。現任蘇寧消費者平臺研發中心前端技術總監,負責蘇寧易購網站前端領域的技術管理工作。在基于 Node.js 的前后端分離,ReactNative/Weex 開發上有豐富的技術實踐經歷。

12 月 7 日北京 ArchSummit 全球架構師峰會上,來自美團、百度、阿里、快手的講師齊聚一堂,共同分享“打造 Native 體驗 Hybrid App 實踐”、“定制統一可維護的前端架構”、“10 年雙十一前端關鍵技術”和“同構 Web App 的另一種探索”的分享。 https://bj2018.archsummit.com/schedule

購票聯系票務灰灰 17326843116

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276757.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276757.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276757.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

wpf: DataGridTextColumn 數字格式顯示,編輯時取消格式(StringFormat)

參考&#xff1a;Format values in a Datagrid 參考&#xff1a;Remove stringFormat while editing cell in datagrid 使用 DataGridTemplateColumn 實現&#xff1a; <DataGridTemplateColumn Header"Cot (k€)"><DataGridTemplateColumn.CellTemplate&g…

MVP群聊某美國公司的應聘試題(壓死九個還是一個)

某美國公司的應聘試題&#xff08;壓死九個還是一個&#xff09;&#xff0c;測試你的管理方式有二條鐵軌&#xff0c;一條新的&#xff0c;一條舊的。有了新鐵軌后&#xff0c;舊鐵軌不再有火車通過。有一天有十個小孩到鐵軌上玩耍&#xff0c;九個小孩在新鐵軌上玩&#xff0…

JS的常用正則表達式 驗證密碼

JS的正則表達式強&#xff1a;字母數字特殊字符 ^(?![a-zA-z]$)(?!\d$)(?![!#$%^&*]$)(?![a-zA-z\d]$)(?![a-zA-z!#$%^&*]$)(?![\d!#$%^&*]$)[a-zA-Z\d!#$%^&*]$中&#xff1a;字母數字&#xff0c;字母特殊字符&#xff0c;數字特殊字符^(?![a-zA-z]$)…

微軟宣布開源WPF、WinForms和WinUI

在微軟Connect 2018大會上&#xff0c;微軟發布了.NET Core 3.0的第一個預覽版。同時&#xff0c;微軟還宣布&#xff0c;他們將WPF、Windows Forms&#xff08;WinForms&#xff09;和WinUI作為開源項目托管在GitHub上。它們都是基于MIT許可發行&#xff0c;開發人員可以在自己…

帆軟報表(finereport)使用Event 事件對象 (target)修改提示框樣式

target 事件屬性 Event 對象 定義和用法 target 事件屬性可返回事件的目標節點&#xff08;觸發該事件的節點&#xff09;&#xff0c;如生成事件的元素、文檔或窗口。 語法 event.target 定義結束事件JavaScript JS修改內容提示框樣式-https://help.finereport.com/doc-view-2…

python的開發環境有哪些系統_Win10下配置機器學習python開發環境

近期計劃寫一寫機器學習微信小程序的開發教程&#xff0c;但微信開發工具只提供了Windows和Mac OS版本&#xff0c;作為一名長期使用Linux系統的開發人員&#xff0c;雖然始終認為Linux系統才是對開發者最友好的&#xff0c;但微信團隊作出這種選擇&#xff0c;肯定經過調查。不…

動態添加ContextMenuStrip項(ToolStripItem)

//綁定菜單privatevoidBindMenu(DataTable dt) {foreach(DataRow row indt.Rows) { ToolStripItem item newToolStripMenuItem(); item.Name row[0].ToString(); item.Text row[1].ToString(); item.Click newEventHandler(contextMenuStrip1_ItemClick); contextMenuStrip1.It…

07_00_加載資源(Webpack Book)

Loading Assets(加載資源) In this part, you will learn how to load different types of assets using webpack’s loaders. Especially images, fonts, and JavaScript receive particular attention. You also learn how webpack’s loader definitions work.在這部分&…

html與cgi腳本的配合使用

利用boa服務器測試arm開發板上的cgi和html聯合編程的小例程。很簡單&#xff0c;但是當時覺得很有意思。在這里給大家展示一下&#xff0c;高手飄過。 在ubuntu下安裝boa測試環境&#xff0c;即先在本地搭建一個boa的網頁服務器。apt-get install boa。稍作配置即可。我的Boa按…

zabbix3監控ESXI主機

ESXI主機VMware公司企業級虛擬化的解決方案Vsphere的重要組件&#xff0c;也是虛擬機的宿主機&#xff0c;對其監控有著重要的意義&#xff0c;下邊介紹二種方發對其監控。 方法一&#xff1a;通過修改服務端的控制項來進行監控。 虛擬機監控分兩個步驟完成。首先&#xff0c;Z…

mybatis jar包_springboot2整合mybatis-plus3踩到的坑

前言最近在進行項目重構&#xff0c;在架構師的建議下&#xff0c;就把項目中mybatis切換成mybatis-plus。因為mybatis-plus在mybatis的基礎上只做增強不做改變&#xff0c;因此切換的成本很低&#xff0c;就只需改jar和配置內容&#xff0c;原先的代碼無需改動。因為mybatis-p…

java_二進制的前導的零

題目內容&#xff1a; 計算機內部用二進制來表達所有的值。一個十進制的數字&#xff0c;比如18&#xff0c;在一個32位的計算機內部被表達為00000000000000000000000000011000。可以看到&#xff0c;從左邊數過來&#xff0c;在第一個1之前&#xff0c;有27個0。我們把這些0稱…

共享幾套silverlight2 toolkit最新的皮膚控件樣式下載

下載了最新的silverlight2 toolkit看看&#xff0c;發現里面的控件樣式還是多漂亮的&#xff0c;與大家分享下。 blue dark light orange purple red 樣式源碼下載&#xff1a;點擊下載 當然&#xff0c;我最喜歡的還是orange哦。 轉載于:https://www.cnblogs.com/liaohenchen/…

python爬取同花順_Java爬取同花順股票數據(附源碼)

最近有小伙伴問我能不能抓取同花順的數據&#xff0c;最近股票行情還不錯&#xff0c;想把數據抓下來自己分析分析。我大A股&#xff0c;大家都知道的&#xff0c;一個概念火了&#xff0c;相應的股票就都大漲。 如果能及時獲取股票漲跌信息&#xff0c;那就能在剛開始火起來的…

開會=浪費時間?阿里技術團隊這樣開項目復盤會

2019獨角獸企業重金招聘Python工程師標準>>> 阿里妹導讀&#xff1a;復盤是項目結束后必不可少的階段&#xff0c;好的復盤會議能夠有效地促進團隊成長。今天&#xff0c;阿里項目管理專家鹿迦以自身的經驗&#xff0c;為大家分享如何做好一個項目的復盤。這篇文章分…

Spring @Value注解無法正確賦值問題

正確的調用方式為&#xff1a; Component public class IconProperties {Value("${icon.url}")private String url; } public class test{AutowiredIconProperties icon;public void test(){ String url icon.url; } } 這里有三個需要注意的點&#xff1a; 1.Value…

Extjs中使用FusionChart舉例

一 前言&#xff1a; 在項目實施中&#xff0c;設計統計部分經常會使用圖表進行顯示&#xff0c;在Extjs3中內置了圖表控件&#xff0c;但實際表現無法達到3D的美觀效果&#xff0c;通過查找FusionChart可以實現比較美觀的3D或2D圖表顯示。注&#xff1a;FusionChart是個商業…

drawitem設置指定行的背景顏色_Java 為 Excel 中的行設置交替背景色

點擊上方 好好學java &#xff0c;選擇 星標 公眾號重磅資訊、干貨&#xff0c;第一時間送達今日推薦&#xff1a;牛人 20000 字的 Spring Cloud 總結&#xff0c;太硬核了~作者&#xff1a;Jazzz鏈接&#xff1a;https://www.cnblogs.com/jazz-z/p/12665819.html在制作Excel表…

常見的關系型數據庫和非關系型數據及其區別

一、關系型數據庫 關系型數據庫最典型的數據結構是表&#xff0c;由二維表及其之間的聯系所組成的一個數據組織 優點&#xff1a;1、易于維護&#xff1a;都是使用表結構&#xff0c;格式一致&#xff1b;2、使用方便&#xff1a;SQL語言通用&#xff0c;可用于復雜查詢&#x…

逆序數技巧 - 牛客

鏈接&#xff1a;https://ac.nowcoder.com/acm/contest/308/D來源&#xff1a;牛客網 題目描述 tokitsukaze給你一個長度為n的序列&#xff0c;這個序列是1到n的一種排列。然后她會進行q次操作。每次操作會給你L R k這三個數&#xff0c;表示區間[L,R]往右移動k次。移動一次的…