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

客戶介紹

語雀是一個專業的雲端知識庫,用於團隊的文檔協作。現在已是阿里員工進行文檔編寫和知識沉澱的標配,並於 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 上。

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章