天天看點

函數計算助力語雀建構穩定且安全的業務架構

客戶介紹

語雀是一個專業的雲端知識庫,用于團隊的文檔協作。現在已是阿裡員工進行文檔編寫和知識沉澱的标配,并于 2018 年開始對外提供服務。

客戶痛點

語雀是一個複雜的 Web 應用,也是一個典型的資料密集型應用(Data-Intensive Application),背後依賴了大量的資料庫等雲服務。語雀服務端是 Node.js 技術棧。當提到 Node 的時候,可能立刻就會有幾個詞浮現在我們腦海之中:單線程(single-threaded)、非阻塞(non-blocking)、異步(asynchronously programming),這些特性一方面非常的适合于建構可擴充的網絡應用,用來實作 Web 服務這類 I/O 密集型的應用,另一方面它也是大家一直對 Node 诟病的地方,對 CPU 密集型的場景不夠友好,一旦有任何阻塞程序的方法被執行,整個程序就被阻塞。

像語雀這樣用 Node 實作整個服務端邏輯的應用,很難保證不會出現一些場景可能會消耗大量 CPU 甚至是死循環阻塞程序的,以 markdown 轉換舉例,由于使用者的輸入無法窮舉,總有各種可能讓轉換代碼進入到一個低效甚至是死循環的場景之中。在 Node 剛出世的年代,很難給這些問題找到完美的解決辦法,而即便是 Java 等基于線程并發模型的語言,在遇到這樣的場景也很頭痛,畢竟 CPU 對于 Web 應用來說都是非常重要的資源。而随着基礎設定越來越完善,當函數計算出現時,Node 最大的短闆看起來有了一個比較完美的解決方案。

解決方案

“把函數計算引入之後,我們可以将那些 CPU 密集型、存在不穩定因素的操作統統放到函數計算服務中去執行,而我們的主服務再次回歸到了 I/O 密集型應用模型,又可以愉快的享受 Node 給我們帶來的高效研發福利了!”語雀産品技術負責人不四表示。

“以語雀中遇到的一個實際場景來舉例,使用者傳入了一些 HTML 或者 Markdown 格式的文檔内容,我們需要将其轉換成為語雀自己的文檔格式。在絕大部分情況下,解析使用者輸入的内容都很快,然而依然存在某些無法預料到的場景會觸發解析器的 bug 而導緻死循環的出現,甚至我們不太敢更新 Markdown 解析庫和相關插件以免引入更多的問題。但是随着函數計算的引入,我們将這個消耗 CPU 的轉換邏輯放到函數計算上,語雀的主服務穩定性不會再被影響。”

函數計算助力語雀建構穩定且安全的業務架構

除了幫助 Web 系統分擔一些 CPU 密集型操作以外,函數計算還能做什麼呢?

語雀支援使用各種代碼形式來繪圖,包括 Plantuml、公式、Mermaid,還有一些将文檔導出成 PDF、圖檔等功能。這些場景有兩個特點:

1、他們依賴于一些複雜的應用軟體,例如 Puppeteer、Graphviz 等;

2、可能需要執行使用者輸入的内容;

支援這類場景看似簡單,通過 process.exec 子程序調用一下就搞定了。但是當我們想把它做成一個穩定的對外服務時,問題就出現了。這些複雜的應用軟體可能從設計上并沒有考慮要長期運作,長期運作時的記憶體占用、穩定性可能會有一些問題,同時在被大并發調用時,對 CPU 的壓力非常大。再加上有些場景需要運作使用者輸入的代碼,攻擊者通過建構惡意輸入,可以在伺服器上運作攻擊代碼,非常危險。

在沒有引入函數計算之前,語雀為了支援這些功能,盡管單獨配置設定了一個任務叢集,在上面運作這些三方服務,接受主服務的請求來避免影響主服務的穩定性。但是為了解決上面提到的一系列問題還需要付出很大的成本:

1、需要維持一個不小的任務叢集,盡管可能大部分時間都用不上那麼多資源。

2、需要定時對三方應用軟體進行重新開機,避免長時間運作帶來的記憶體洩露,即便如此有些特殊請求也會造成第三方軟體的不穩定。

3、對使用者的輸入進行檢測和過濾,防止黑客惡意攻擊,而黑客的攻擊代碼很難完全防住,安全風險依舊很大。

函數計算助力語雀建構穩定且安全的業務架構

最後語雀将所有的第三方服務都分别打包在函數中,将這個任務叢集上的功能都拆分成了一系列的函數放到了函數計算上。通過函數計算的特點一下解決了上面的所有問題:

1、函數計算的計費模式是按照代碼實際運作的 CPU 時間計費,不需要長期維護一個任務叢集了。

2、函數計算上的函數運作時盡管會有一些常駐函數的優化,但是基本不用考慮長期運作帶來的一系列問題,且每次調用之間都互相獨立,不會互相影響。

3、使用者的輸入代碼是運作在一個沙箱容器中,即便不對使用者輸入做任何過濾,惡意攻擊者也拿不到任何敏感資訊,同時也無法進入内部網絡執行代碼,更加安全。

函數計算助力語雀建構穩定且安全的業務架構

除了上面提到的這些功能之外,語雀最近還使用 OSS + 函數計算替換了之前使用的阿裡雲視訊點播服務來進行視訊和音頻的轉碼。

由于浏覽器可以直接支援播放的音視訊格式并不多,大量使用者上傳的視訊想要能夠直接在語雀上進行播放需要對它們進行轉碼,業界一般都是通過 FFmpeg 來對音視訊進行轉碼的。轉碼服務也是一個典型的 CPU 密集型場景,如果要自己搭建視訊轉碼叢集會面臨大量的資源浪費,而使用阿裡雲視訊點播服務,成本也比較高,而且能夠控制的東西也不夠多。函數計算直接內建了 FFmpeg 提供音視訊處理能力,并內建到應用中心,配合 SLS 完善了監控和資料分析。語雀将音視訊處理從視訊點播服務遷移到函數計算之後,通過優化壓縮率、減少不必要的轉碼等優化,将費用降低至之前的 1/5。

函數計算助力語雀建構穩定且安全的業務架構

使用效果

語雀産品技術負責人不四表示:從語雀的實踐來看,語雀并沒有像 SFF 一樣将 Web 服務遷移到函數計算之上(SFF 模式并不是現在的函數計算架構所擅長的),但是函數計算在語雀整體的架構中對穩定性、安全性和成本控制起到了非常重要的作用。總結下來函數計算非常适合下面幾種場景:

1、對于時效性要求不算非常高的 CPU 密集型操作,分擔主服務 CPU 壓力。

2、當做沙箱環境執行使用者送出的代碼。

3、運作不穩定的三方應用軟體服務。

4、需要很強動态伸縮能力的服務。

在引入函數計算之後,語雀現階段的架構變成了以一個 Monolith Application 為核心,并将一些獨立的功能子產品根據使用場景和對能力的要求分别拆分成了 Microservices 和 Serverless 架構。應用架構與團隊成員組成、業務形态息息相關,但是随着各種雲服務與基礎設施的完善,我們可以更自如的選擇更合适的架構。

由于 Serverless 的出現,我們可以将這些存在安全風險的,消耗大量 CPU 計算的任務都遷移到函數計算上。它運作在沙箱環境中,不用擔心使用者的惡意代碼造成安全風險,同時将這些 CPU 密集型的任務從主服務中剝離,避免出現并發時阻塞主服務。按需付費的方式也可以大大節約成本,不需要為低頻功能場景部署一個常駐服務。是以我們會盡量的把這類服務都遷移到 Serverless 上。