作者 | 淩恒

Alinode 作為一款強大的 Node.js 性能診斷産品,服務了阿裡集團内外很多的 Node.js 開發者,幫助他們定位、解決了大量性能相關問題,有着良好的口碑。随着雲原生時代的到來,Serverless 浪潮席卷了整個開發者社群,Node.js 也不例外,Alinode 如何在去發揮更大的價值,是我們在接手 Alinode 品牌後一直在思考的事情,過去的一年,我們給 Alinode 定義了兩個發展方向:觀測性和排程性,簡單給大家分享一下我們圍繞這兩個方向做的一些事情。
觀測性(Alinode Insight)
平台
從平台出發,我們将兩個産品的能力進行了融合成了新的平台 Alinode Insight,将平台定位由性能平台轉向了全方位的應用監控與錯誤追蹤平台,能夠協助使用者更快地發現、解決問題。
在傳統 Node.js 應用場景,開發者對應用本身可掌控的程度比較高,會有很多手段來觀測應用狀态、排查應用問題,動手能力強的也會根據需求搭建業務所需的平台。相對來說,觀測平台作用更多的是輔助開發者的工作,作為一個白屏化操作的工具。
然而,在 Serverless 的模式下,開發者除了代碼,能接觸到的細節基本被屏蔽,更多的是依賴各種平台提供的服務來管理,是以觀測平台的能力越發顯得重要起來,要能夠給使用者提供全面的觀測體系,幫助使用者剖析代碼運作的過程。
我們從一些案例出來,來看下觀測平台發揮的作用。
流量狀态
使用者收到函數成功率下降報警,通過流量趨勢可以看到,在 03:16 分左右,某單元異常率上升,馬上根據預案采取措施,将風險屏蔽。
另一個比較常見的情況,函數下遊經常會發生抖動,通過鍊路資訊,我們可以快速的發現異常的服務:
可以看到是某一單元的下遊服務發生了異常,進而采取相關的預案來規避風險。
當然,這些資料的展示,都是觀測平台的基本能力,下面我們看一些跟函數開發更相關的能力,目前這些能力主要和阿裡雲函數計算團隊合作。
白屏化日志
函數釋出後,不能像之前應用一樣,登陸到伺服器上檢視日志,這對使用者排查問題造成了很大的困擾。
為此,我們提供了函數産生的所有日志的查詢能力,可以檢視每一次請求所産生的日志,同時在鍊路、日志、異常間建立了聯系,這樣能夠更友善的定位問題,當然也包括對日志上下文的查詢。
還可以通過啟動日志定位函數或者應用遷移後在啟動過程中遇到的問題,以及通過 SLS 查詢文法,進行高階查詢。
遠端調試
如何在運作環境中調試函數,也是使用者碰到的一個難點,因為函數計算的特殊運作架構,傳統手段難以實施。雖然阿裡雲函數計算控制台提供了線上編輯、釋出、運作的能力,但使用者往往會陷入“改代碼加日志→釋出→通路→查日志”這樣的循環,效率比較低。
為了提升排查效率,我們将遠端調試能力在阿裡雲函數計算環境實作了落地,目前在部分區域灰階中,相信大家很快就可以用上了,可以先通過動圖感受一下(正式上線 UI 可能略有變化)。
崩潰分析
在使用函數計算的使用者,日常比較常遇到的情況就是函數挂掉了,但是不知道為什麼挂掉,之前還可以通過 coredump 分析,但現在隻能通過日志來獲得資訊。
我們從 Node.js 本身找到了解決方案,在 Node.js v12 之後內建了 Report API,能夠在程序異常退出的時候生成 Diagnostic report,類似 Alinode 之前提供的能力,隻不過更加詳細。通過這份報告,我們可以檢視 JavaScript 和 native 堆棧資訊,堆統計,平台資訊,資源使用情況等,為排查工作提供更多資料支援。
目前我們在内部實踐驗證這個能力,會盡快和函數計算團隊配合,開放到公有雲中。
以上這些能力,會封裝成一個開箱即用的解決方案,在函數計算團隊後續的釋出會中,開放使用。除了和函數計算團隊的合作,我們還和阿裡雲的 ARMS 團隊有良好的合作,在 Node.js 可觀測性上發力,後續也能慢慢看到這些能力的開放。
标準化
在平台之下,我們在觀測資料标準化上,也做了不少工作。
Alinode 診斷探針
随着 Node.js 應用規模的擴大,社群使用者對 Diagnostic 的需求也越來越多,是以 Node.js 專門成立了 Diagnostics Working Group,裡面有很多 APM 廠商以及興趣相投的人,比如我們熟知的 Joyee Cheung。
通過這個工作組,更多的 Diagnostic 能力被整合到了 Node.js 本身,相比于 Alinode,僅在 GC 名額、資料導出、信号量處理上有些差異,完全可以通過 addon 的形式抽離出來,更容易通過 npm 元件分發以及部署,也更符合社群的需求。如果需要特定的 API,也會通過社群提案方式申請開放,減少對原生版本的修改。這跟很多 APM 的思路是類似的,比如像 Easy-Monitor。
推動标準
Pandora.js 作為一個開源産品,可能會面對使用者形形色色的已有系統,如何能将資料和平台解耦,讓其具有普适性。
我們從雲原生體系中找到了答案——OpenTelemetry,它整合了 OpenTracing 和 OpenCensus,已經成為了雲原生監控方向上的首要标準,具有良好的普适性,正是我們所需要的,是以我們将 Pandora.js 的資料體系基于 OpenTelemetry 進行了重構,使用标準的 metrics,traces,logs 格式,通過 exporter 實作跨平台能力。同時,這個标準還是在發展中,我們還可以在使用的同時參與到它的建設中,将我們的想法和衆多同道中人碰撞,産生更多有意義的内容。
另一個我們在積極推進的就是「Async Context for JavaScript」提案,它影響着目前 Node.js Async Hooks,Async Storage 等能力的性能和接口,對 Node.js 無感覺鍊路追蹤的實作有着重大意義,也是很多 Node.js 開發者關注的功能,能為很多場景帶來更好的體驗。
除了這些,團隊還提出了國内第一個 Stage 3 提案「Error Cause」。
排程性(Alinode Cloud)
Alinode Runtime 誕生之初就是希望能夠幫助使用者更高效的解決 Node.js 的疑難雜症,從過往來看也不辱使命。現在的雲原生時代,仍會有更多新的問題等待着 Alinode Runtime 去突破。在過去的一年,我們主要“成本”和“性能”間尋求平衡。
加載速度優化
衆所衆知,Serverless 能夠有效的優化成本,而“彈性”則是這一過程必不可少的手段。為了更好的實作彈性,啟動速度是很關鍵的一環。是以,上一年,我們一直在探索降低 Node.js FaaS Runtime 的啟動時間,取得了不錯的效果,但我們重點是在 Runtime 本身的優化,是針對特定、可控的代碼優化,不具備普适性,從實際的落地效果來看,整體函數可服務時間裡,使用者代碼加載耗時比重遠高于 Runtime 本身,如果能把這部分耗時縮短,那麼效果會更加明顯。
使用者代碼加載時間優化主要有兩個難點:
- 依賴多樣且複雜,存在大量狀态
- 優化不能讓使用者有感覺
已知最有可能的方案,就是 V8 提供的 Snapshot 能力,将使用者的運作後的記憶體狀态存儲,然後在需要的時候還原。但實作起來,使用者負責的代碼狀态很難維護,包括 Node.js 本身在 Snapshot 上的使用也進展緩慢,而且也難以随着應用在不同機器間分發。
在計算機領域,我們常用的兩個優化手段:空間換時間,時間換空間。我們希望在時間上取得收益,就得在空間上有所投入。為此我們設計了一個存儲結構,将使用者引用的所有内容存儲起來,在啟動加載時,根據這個結構來加載依賴,能夠大幅減少系統調用的開銷。這個結構可以在建構或者部署前生成,用一次建構的消耗時間,能夠換來在實際生産環境的加載時間大幅縮短,是很值得的。
目前,從我們在業務落地的效果來看,收益還是很可觀的,部分資料如下(包含網絡開銷):
彈性效率優化
在認知上,我們認為 Serverless 應該是毫秒級彈起、亞秒級傳遞的,是能實作資源高效利用的,但現狀遠遠低于預期。為此,我們也在思考,從 Alinode Runtime 視角,怎麼能夠優化彈性效率,實作高效資源利用。我們從現狀整理了三個問題:
- 函數容器能否啟動的更快
- 資源成本能否再壓榨
- 函數能否加載的更快
解決這個問題,我們首先想到一個詞就是“高密度部署”,通過将多個函數部署在同一個執行個體中,充分利用執行個體性能,減少資源浪費。以零弌在 D2 分享中的一張圖為例,讓函數以更小的資源(0.5C512M)運作在執行個體(4C8G)中,能夠同時運作更多的執行個體。
另一個比較容易了解的例子,我們最常使用的 Chrome 浏覽器。當你打開比較多的頁面時,我們可以通過點選右上角“選項”→“更多工具”→“任務管理器”打開一個 Chrome 的任務管理器視窗,可以看到每個打開的 Tab 都對應着一個程序,裡面還包括使用的擴充。
這正是 Chrome 采用的多程序架構,每個頁籤都擁有獨立的渲染器程序。如果一個頁籤沒有響應,則可以關閉無響應的頁籤,并繼續使用,同時保持其他頁籤處于活動狀态。如果所有頁籤,都在一個程序上運作,則當一個頁籤無響應時,所有頁籤都不會響應。這樣做的另一個好處就是,可以提供安全性和沙盒能力,能夠通過對程序權限的限制,比如:限制檔案讀寫權限等。
但是程序多了,資源消耗也會增加,對此,Chrome 會将很多公共能力服務化,在受限的情況下跑在一個程序裡,進而節省記憶體。
如果将這套架構和之前高密度部署結合,就可以在控制函數資源使用的情況下更好的利用資源。
那如何能夠讓函數啟動的更快呢?Cloudflare 給了我們一個很好的思路,通過提供有限的運作時能力,減少程序啟動時加載的内容,來讓程序啟動的更快。有舍必有得,更快的啟動速度,讓彈性更加具有意義。
綜合上面的一些思考,我們實作了 Alinode Cloud Runtime 架構,一套面向 OCI 标準的 Node.js Serverless 基礎平台,在内部實際落地中,取得了不錯的成本控制效果。
之後,我們會在大促等極限場景更好的進行驗證,也希望能夠早日對外開放使用,為 Node.js FaaS 提供一種新的想象。
總結
雲原生時代,帶來了很多契機,Alinode 即是受益者,也是參與者,我們希望:
- 通過 Alinode Insight,希望能夠幫助開發者快速掌握 Serverelss 的研發模式,解決遇到的各種問題;
- 通過 Alinode Cloud Runtime,實作在 Serverless 時代的轉型,由 Runtime 參與者變成定義者。
歡迎更多有想法的同學,來深入交流。或者可以加入我們,來讓 Node.js Serverless 變得更好。([email protected])