[ 好文分享 ] 美團酒店Node全棧開發實踐

轉自:美團技術團隊
做者:美團技術團隊
分享理由:很好的分享,可見,基於Node的先後端分離的架構是越顯流行和重要,前端攻城獅們,Node學起來啊!!html

clipboard.png

先後端分離的背景

「先後端分離」顯然已不是什麼新鮮的話題,Zakas在2013年10月份就曾發表過一篇博客《Node.js and the new web front-end》討論Node背景下新時代的前端。毫無疑問,Node的出現給JavaScript語言帶來了新的生機,也使得前端開發者有了更多的可能性。前端

先後端分離表面上看彷佛是一場「圈地運動」,但實質上先後端分離是爲了解決以往開發模式的一些詬病和痛點,同時也是迎合大的行業趨勢的明智之舉。我所在的美團酒店事業部去年7月份成立,新的業務、新的開發團隊,這一切使得咱們的先後端分離推動的很完全。截至目前,前端承載的全部業務和線上服務都是基於Node,生產環境已經有近20臺服務器。如此帶來的全新先後端協做方式可以讓專業的人作專業的事,不管前端後端都能較以前更專一在本身擅長的方面。node

開發模式、技術棧

clipboard.png

傳統的開發模式只須要專一在多終端的呈現上(瀏覽器、WebView)。而如今,瀏覽器只是前端的其中一環,延伸出來的還有Node端的架構、服務的運維能力等。上圖是咱們目前的服務架構:Nginx位於Node服務以前,用作負載均衡、服務調度、Gzip壓縮等。以後即是Node服務,咱們經過PM2.5進行Node服務的Cluster部署和負載均衡(充分利用多核優點),同時做爲輕量的中間層,負責路由、Controllers、Views、以及視圖的渲染,數據的獲取經過RESTful的API接口使用JSON格式交互。然後端則只須要負責業務邏輯、數據存儲、Models,併爲前端提供JSON數據便可。web

這樣改變以後,Node端能夠進行首屏渲染等頁面加載方面的優化,頁面渲染出來以後後續的交互、渲染都交由瀏覽器端的JavaScript代碼來完成,Node端的模板和瀏覽器端的模板大部分狀況下都是相同的,因此咱們須要考慮模板重用的問題。咱們用Juicer替換了Express框架默認的模板引擎,Juicer是一個高效、輕量的前端 (Javascript) 模板引擎,效率和易用是它追求的目標。除此以外,它還能夠運行在 Node.js 環境中。經過Juicer,能夠解決Node端和瀏覽器端的模板、Helper複用問題。並且基於先後端分離的工程架構下,前端的代碼倉庫和後端隔離,前端獨立負責前端靜態資源文件、模板文件、Controller的維護和發佈。後端

按照這樣從新定義先後端分工以後,前端能夠作的事情較以往更多了,好比微信SDK的接入,由於微信JS SDK的使用須要在服務端進行簽名,因此如今咱們不須要後端介入,前端徹底能夠獨立完成微信SDK的接入。此外像咱們內部和商家端SSO登陸邏輯的接入都徹底由前端獨立完成。瀏覽器

技術選型的思考

對於前端的技術選型,咱們始終保持理性、擁抱的態度。咱們不會爲了盲目求新而引入新的技術,技術選型是針對咱們目前大團隊的場景,爲了解決以往協做過程當中發現的一些痛點和不足。好比引入Node是爲了改進先後端的工做流和效率,提高先後端的開發體驗。再好比目前咱們項目中採用的Angular、React也是針對特定的業務場景,爲了提高開發效率、加強代碼的可維護性。在咱們的業務應用中,面向商家、後臺的一些增刪改查系統,Angular可以顯著的提高開發效率,而React咱們目前只是在面向用戶的PC端項目中在作一些嘗試和實踐。緩存

帶來的挑戰

這樣的分工和架構模式在給前端帶來更多可能性、更多便利的同時,也帶來了不小的挑戰,相比傳統的前端角色而言,咱們須要更多的關注線上服務的狀態,進程內存佔用、CPU佔用的詳細情況,以及線上異常的監控等。在咱們擁抱Node的同時,對前端的能力要求是更上一階的。一段看起來正常的JS代碼,在瀏覽器端和在Node端兩種不一樣的運行環境下,就可能會暴露出一些以往關注不到的問題,好比內存泄露:一個閉包或者一個用於緩存數據的對象,跟瀏覽器不一樣,Node對內存泄露十分敏感,由於線上應用有成千上萬甚至百萬計的流量,因此哪怕是一個字節的內存泄露也會形成內存堆積,從而致使垃圾回收過程耗時增長,應用響應緩慢,知道進程內存溢出,應用重啓或崩潰。服務器

內存泄露問題的定位

如下是咱們在生產環境遭遇的一個案例:最近發現線上服務的內存佔用在服務重啓後會呈線性的增加,進程啓動18小時後,內存就已經佔用接近1.6G左右,以後不久便會超過V8的內存限制致使服務重啓。從圖中能夠看出,在修復以前內存使用狀況一直在隨時間進行週期性的波動,波動的緣由就是線上Node進程不斷的重啓致使的。微信

clipboard.png
衆所周知,在V8的垃圾回收機制下,通常的代碼不多出現內存泄露的狀況,可是一旦出現內存泄露每每較難排查。但形成內存泄露的本質緣由只有一個,就是應當回收的對象沒有正常被回收,變成了老生代中的常駐對象。好在藉助一些常見的排查工具能夠幫助咱們定位內存泄露的具體緣由:網絡

- v8-profiler
- node-heapdump
- node-mtrace
- dtrace
- node-memwatch

這裏咱們使用node-heapdump來在模擬訪問的條件下生成堆內存的snapshot,並經過Chrome的開發者調試工具對生成的snapshot文件進行分析。經過對比服務剛啓動時以及使用AB模擬併發訪問一段時間後的heapdump信息能夠比較容易的定位到內存泄露的問題點:是由於Juicer默認開啓了cache,會默認對編譯後的模板進行緩存,所以隨着訪問的增加和併發請求,cache對象會持續增加且不被回收,因而關閉cache並從新部署上線後線上恢復正常。

因爲在瀏覽器的場景中運行時間短,且運行在用戶的機器上,即使內存使用過多或者內存泄露,也只會影響到用戶的終端。並且運行時間短,隨着進程的退出,內存也會隨之釋放,幾乎沒有太多內存管理的必要。但在Node端一樣的代碼就可能會暴露出問題。

線上服務的運維和監控

先後端分離除了意味着代碼倉庫的分離、開發協做的分離以外,還涉及到線上服務的獨立發佈和單獨部署。與之俱來的固然是前端如何更好地對線上服務進行更細粒度的運維和監控,咱們的SA會更多的關注線上服務的總體指標和可用性,而前端更但願可以細粒度的瞭解線上Node的進程狀態以及異常狀況。

PM2是一款優秀且開源的Node進程管理工具。咱們在PM2的基礎上作了一些改造,同時在雲端部署了數據收集、數據實時獲取的服務,從而造成了咱們目前已經應用到線上的Node部署監控平臺PM2.5,它能夠將線上Node服務進程級別的細粒度信息聚合在雲端進行處理和可視化展示,PM2.5可以監控Node Server和進程的各項指標狀態,且能夠配置報警並在各終端(Web、iPhone、Apple Watch)展現。

PM2.5的服務架構

簡單介紹下PM2.5的服務架構:生產環境的Node服務經過PM2.5 CLI進行部署,PM2.5 CLI會持續不斷的將Node進程的各項數據上報到PM2.5的雲端。雲端收到上報的數據後會對原始數據進行處理並存儲至MongoDB。而Web端和iOS應用都會經過WebSocket服務從服務端得到實時的數據流,而後經過前端進行可視化的信息展現。

clipboard.png

PM2.5的內部實現

當Node進程經過PM2.5啓動時,PM2.5 CLI會同雲端服務進行握手,握手成功後纔會源源不斷的進行數據的上報。上報時首先會將數據進行AES256加密,而後使用TCP通訊將數據上報到服務器,這裏用到了開源的Axon,雲端服務器收到數據後會將數據入庫存儲到MongoDB中,同時會進行監控報警的掃描,若是當前數據符合用戶訂閱的監控報警條件,則會經過雲端的Push服務向iOS客戶端推送報警信息。雲端同時運行WebSocket服務,爲多個終端(Web平臺、iOS應用)提供實時數據的推送。

這裏值得一提的是,PM2.5的客戶端是基於React-Native開發,目前已經提交Apple Store正在審覈,審覈經過後就能夠從Apple Store中下載到了,客戶端提供了服務和進程基本指標的查看,同時能夠配合Web平臺的監控報警設置實現7x24小時對服務的監控。

clipboard.png

其它監控設施的接入

爲了確保線上服務的可靠、穩定,咱們還接入了其它一些監控設施和日誌平臺,便於對線上的錯誤和訪問日誌進行追蹤、分析和定位處理。

Zabbix

Zabbix是一種分佈式系統監控以及網絡監控功能的企業級開源中間件,主要是被運維使用。Zabbix主要用於對服務進行心跳檢測、監控服務的各項指標,當某些指標異常或超過設定的閾值時進行短信、大象、郵件的報警。

Sentry 錯誤日誌收集

Sentry是一個錯誤日誌服務器,能夠將程序錯誤的詳細狀況集中捕獲。並且提供各類常見語言的SDK供業務接入。但Sentry在服務器端會有采樣,通常不能替代實時錯誤日誌報警的監控。

日誌監控平臺

日誌監控平臺是美團內部的一個日誌收集系統,目前美團統一使用flume收集日誌,flume具備接收scribe格式日誌的能力,而日誌監控平臺也是以scibe格式日誌來收集。日誌在整個收集流程中以兩種形式存在,分別是原始日誌和解析後的日誌。目前咱們使用日誌監控平臺主要用於將訪問日誌的格式化數據上報,以後就能夠經過Hive/Presto對訪問數據進行查詢了。

性能監控平臺

性能監控平臺爲美團各平臺和產品線提供簡單易用的、端到端的性能數據服務。同時也提供了各類常見語言的SDK供業務接入。主要用於分析Node端的接口響應,以及瀏覽器端的頁面載入性能。

小結

以上是美團酒店前端在應用Node進行全棧開發的過程當中摸索前行的一些心得,也是引子,主要介紹了咱們酒店事業部的先後端分離架構,線上內存泄露問題的排查,和所使用的Node服務監控平臺PM2.5,後續我會分享更多咱們的Node方面的一些實踐,以及PM2.5監控平臺的背後實現,但願能對你有所幫助,也歡迎你們可以參與進來共同交流先後端分離和Node相關的技術點。

相關文章
相關標籤/搜索