當前位置:
首頁 > 最新 > 引入Serverless/FaaS時機到了?國外Hootsuite的Serverless架構實踐

引入Serverless/FaaS時機到了?國外Hootsuite的Serverless架構實踐

導讀:業界有不少 FaaS/Serverless 方面討論,不少的架構師對引入類似的架構仍然存在一些顧慮,今天文章介紹一篇國外 Hootsuite 是用 Serverless 的案例,供考慮引入 FaaS 的同行參考。

Harry Huang,目前是 Hootsuite 的一名全棧工程師。Hootsuite 是一家創立於 2008 年來自加拿大的著名社交媒體管理工具。

背景

隨著業界公司都將架構演進到面向服務的架構 (Service oriented Architecture),越來越多的服務會轉移到「雲」中。

資料庫、文件存儲、各種伺服器都正在慢慢地轉移到雲端,他們在虛擬容器中運行,而不是像以前一樣跑在專用的主機上。

最近流行起來的 FaaS(Function as a Service)可以使開發人員將「應用的業務邏輯」上傳到雲端,不用考慮伺服器或其他外部依賴,實質上是被抽象成了函數(Function)。

儘管如此,開發人員依然需要處理和「雲」密切相關的環節,比如上傳、部署、版本控制等等,這些複雜性與 FaaS 其他一些局限性共同構成了 Serverless 架構。

動機

Serverless 框架允許我們將開發過程中和「雲」相關的部分抽象出來,開發人員可以直接編寫應用程序實際的業務邏輯代碼。除此之外,Serverless 架構還具備其他優點,比如更低成本和易擴展。

既然這樣,我們會思考是否可以完全使用 Serverless 架構替代現有的架構模式呢?下面我們就著手構建一個功能齊全的,基於雲的,符合 Serverless 架構的應用。

我們構建了什麼?

我們創建了一個服務於 Hootsuite 內部工程師的小系統,工程師們可以列出自己的技能和興趣,可以創建、搜索內部項目,也可以根據技能和興趣加入項目。

整個系統的後端完全基於 AWS Lambda,它是 Amazon 的事件驅動 FaaS 平台,服務以 Lambda 函數的形式提供。

設計階段,我們需要函數能夠完成:

另外,函數還要能夠集成其他服務。

整個項目中我們使用了以下 AWS 的服務[1]:

以及一些第三方服務:

對於單頁應用的前端:

同時,我們在項目中使用 Serverless Framework[4] 來測試和部署我們的基礎設施。這樣我們就不用操心 AWS 相關的配置或任何 DevOps 相關的事情,我們能夠專註於編寫應用的邏輯代碼,照著里程碑快速推進。

約束

在正式開始之前,我們最好明確和統一一下認知。 Lambda,意如其名,就是匿名函數。因此,我們的後端實現基本上就限制於單一獨立的函數調用,我們可用的其他資源就是雲上的存儲和服務。這種 Serverless 架構模式下我們就會面對一些約束:

無狀態性

Lambda 函數本身是事件驅動的,所以自然是無狀態的。來自客戶端的每個事件就是一個函數的單個調用,所以通常將狀態存儲於內存(如Redis)。在我們的例子中,我們使用DynamoDB 進行存儲和檢索。因此,我們的流程必須設計成單一的,獨立的,無狀態的函數組成。

長耗時的任務

目前,Lambda 函數有5分鐘的執行時長限制,顯然傳統的架構中是沒有這樣限制的。這使得需要長耗時的任務,比如處理數據流面臨挑戰性。如果有任務需要耗時5分鐘以上,那麼任務必須被拆分,同時還需要追蹤數據塊和狀態。對於定時任務或計劃任務,可以藉助 Cloudwatch 來設置時間間隔。

冷啟動

當 Lambda 函數無調用時,雲端通常會 Spin down 該函數。當再有調用時,函數的運行時容器會先將函數 Spin up。這意味著設置執行環境所產生的任何開銷,比如 JVM 層面的初始化等,都會增加函數執行的額外延遲。Neil Powers 和 Paul Cowles 之前給出了一個函數啟動時間的分析報告[5]。

對於後台任務或者守護任務這倒沒關係。但是,對於我們正在構建的應用,冷啟動造成的延遲將會直接影響用戶的前端體驗。比如 Java 實現的函數,冷啟動時可以通過類似「ping 請求」,來儘可能降低延遲。對於我們的應用,最終選擇 Node.js 作為函數載體,因為它的冷啟動延遲最小[6]。

依賴

Lambda 的優點和缺點基本都源於 AWS Lambda 執行模型的工作原理。

由此可見,AWS Lambda 會自動進行水平擴展。但由於每個函數都有自己獨立的執行容器,所以每個容器都有創建開銷。這也意味著簡單得將一個 Lambda 函數拆分成幾個小的 Lambda 函數會進一步增加開銷。

由於執行容器是按需創建的,因此AWS Lambda 不能保證這些函數將在同一個內存空間甚至同一台機器上運行。這與傳統架構模型不同,Lambda 函數不是「本地(locality)」的,在雲上需要來回傳遞狀態。

如果若干函數必須鏈式執行,那應該完全在雲端執行此操作,而不是在客戶端(比如 user facing 的功能)。這裡可以藉助 Amazon SNS 進行消息傳遞,也可以使用 AWS Step Functions[7] 來執行函數工作流。

認證

這部分與 Serverless 架構關係不大,主要展示我們的應用如何通過 BaaS(Backend as a Service)來實現認證。所有認證邏輯都由 BaaS 提供。

我們應用用戶將和幾個 AWS 服務進行交互,我們需要一種方式來管理身份驗證以及不同 AWS 服務許可權和 API 訪問許可權的控制。藉助 Amazon IAM 和 Cognito,我們可以在控制台內配置和管理許可權。

這樣用戶通過驗證身份,獲得用戶所屬角色,繼而獲得各種許可權。我們能夠處理,維護用戶目錄,我們也可以通過令牌進行身份驗證,同時所有內容都保存在雲中,工作流程如下所示。

完整的 Serverless 架構

客戶端通過 Amazon API Gateway 來調用我們的 Lambda 函數。 Lambda 函數再調用其他服務的 API 並返回相應的結果。這是一個典型的 Lambda 函數工作流:

還有其他幾種調用 Lambda 函數的方式。 S3,DynamoDB,SES 甚至 Amazon 的 Alexa 都可以觸發 Lambda 函數。例如,我們使用 Cloudwatch 設置計劃事件來觸發 ranking 函數。

另一個常用的是 Amazon Cognito 的預註冊觸發器(pre-signup trigger)。這樣在註冊或登錄工作流程的每個步驟都可以觸發事件並調用函數,我們就可以設計靈活的流程來定製身份驗證。

搜索

Serverless 架構很棒的一個特點就是很易於和其他服務集成。 基於資料庫提供快速,複雜搜索的能力通常需要類似 Elasticsearch 這樣的系統。這與我們的 Serverless 架構相違背,因此我們將搜索的能力委託給 SaaS(Software as a Service)服務商 Algolia。這樣我們就能夠使用它的 API 來索引我們的數據,並通過 Lambda 函數執行查詢。

如下圖:

我們的 Lambda 函數基本上取代了傳統架構中的「服務」層。

前端

對於單頁的 React 應用,通過 API 網關與背後的各個函數通行。所有靜態資源託管在 S3 上,並通過 Cloudfront 提供服務。通過Serverless 架構,我們希望以完全獨立的方式來構建應用中的組件,就像前面羅列的做法。

開發 Lambda 函數

設置好 AWS Lambda 之後的實際開發過程簡單且高效。將你的函數添加到 Serverless Framework 的配置文件後,唯一需要去做的就是編寫實際的業務邏輯函數。

Serverless Framework 可以模擬請求來測試本地的 Lambda 函數。任何輸出和異常都呈現在終端里,就像通過 IDE 運行和調試其他程序一樣方便。

在雲端,任何異常、日誌或調用都會被自動記錄下來。在 Cloudwatch 上可以查看部署的每個函數的每個版本產生的日誌和統計信息。因此如果需要追蹤生產環境中出現錯誤的請求,就可以通過 Cloudwatch 輕鬆完成。

至於上傳和部署,就像在終端中執行單個命令一樣簡單。以前,每次要上傳函數時都需要進行一些 Lambda 上的配置和操作。這要求開發人員自己編寫調試一個腳本來自動執行這個過程。但使用 Serverless Framework,所有這些過程都是內置的和自動化的。與伺服器有關的任何事情都被抽象出來了,真的感覺開發過程是「無伺服器」(server-less)的。

優點

低成本

AWS 的許多服務都有免費套餐,可以滿足開發階段的使用。即便是投入生產環境,Lambda 的定價是基於使用量的,所以如果一個函數沒有被使用,那就不會產生任何費用。Serverless 架構/FaaS 是開發產品原型和輕度使用量應用的更便宜選擇。

降低 Devops 的負擔

隨著 FaaS 的推出,DevOps 大部分負擔已經從「維護主機以及搭建基礎設施」轉移到「維護代碼和雲服務商」。

隨著 Serverless Framework 的誕生,開發人員的代碼越來越接近生產環境,減少了大量 DevOps 工作。正如我們這個項目所體現的,設計架構和搭建伺服器的時間較少,而大部分精力被用來開發實際應用。

確保微服務化

FaaS 模式的後端會客觀上確保微服務化。比如身份驗證和搜索服務,需要一個連續運行的服務,並不適合直接構建在 AWS Lambda 上,我們必須將它們作為單獨的微粒度的服務來構建,或者委派給其他已經存在的服務(就像前面說的 BaaS 服務)。

然後我們的應用可以通過一個函數和它們的 API 集成,它們服務的治理是獨立於我們的應用,但集成用的函數就可作為一個微服務來管理。

微服務架構的優點不必多言,建立一個 Serverless 架構的應用會客觀上確保你構建真正的微服務,並從中受益。

下一步計劃?

Serverless/FaaS 技術在過去一年中獲得了顯著的增長和發展[8]。

我們的項目以及這篇文章都已經證明,Serverless 是開發和部署微服務應用或是 Web 應用的廉價,快速的最佳方法。隨著相關技術的不斷發展,未來容器技術和 Serverless 趨勢很可能融合。即使沒有,擁抱 Serverless 都是值得的。

參考信息

[1] https://aws.amazon.com/

[2] https://www.algolia.com/

[3] https://github.com/laurilehmijoki/s3_website

[4] https://serverless.com/

[5] http://code.hootsuite.com/accelerating-cross-platform-development-with-serverless-microservices/#more-4730

[6] https://www.bouvet.no/bouvet-deler/comparing-java-and-node.js-on-aws-lambda

[7] https://aws.amazon.com/step-functions/

[8] https://serverless.com/blog/ultimate-list-serverless-announcements-reinvent/?rd=true/

本文作者 Harry Huang,由魏佳翻譯。基於移動閱讀的考慮,排版相比原文有所調整。轉載本文請註明出處,技術原創及架構實踐文章,歡迎通過公眾號菜單「聯繫我們」進行投稿。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 高可用架構 的精彩文章:

從滴滴出行業務中台實踐聊聊如何構建大中台架構

TAG:高可用架構 |