無伺服器架構

無伺服器架構是應用程式設計,結合第三方「後端即服務」(BaaS) 服務,和/或包含在「函式即服務」(FaaS) 平台上,以受管理的臨時容器執行的自訂程式碼。透過使用這些概念,以及類似單頁應用程式的相關概念,此類架構大幅減少對傳統持續運作伺服器元件的需求。無伺服器架構可受益於大幅降低的營運成本、複雜度和工程前置時間,但代價是更依賴於供應商依賴關係和相對不成熟的支援服務。

2018 年 5 月 22 日


Photo of Mike Roberts

Mike Roberts 是 Symphonia 的合夥人兼共同創辦人,這是一家專精於雲端架構及其對公司和團隊影響的顧問公司。

在 Mike 的職業生涯中,他曾擔任工程師、技術長和其他介於兩者之間的有趣職位。他長期支持敏捷和 DevOps 價值,並熱衷於雲端技術在協助許多高功能軟體團隊實現此類價值所扮演的角色。他將無伺服器視為雲端系統的下一場演進,因此對其協助團隊及其客戶發揮驚人表現的能力感到興奮。


無伺服器運算,或更簡單地說無伺服器,是軟體架構領域的熱門話題。「三大」雲端供應商(亞馬遜、Google 和 Microsoft)大量投資於無伺服器,而且我們已經看到許多書籍、開源專案、研討會和軟體供應商致力於此主題。但是什麼是無伺服器,為什麼(或不)值得考慮?在本文中,我希望讓您對這些問題稍有了解。

首先,我們將探討無伺服器的「是什麼」。我們稍後將深入探討此方法的優缺點。

什麼是無伺服器?

與軟體中的許多趨勢一樣,對於無伺服器是什麼,沒有明確的看法。首先,它包含兩個不同但重疊的領域

  1. 「無伺服器」一詞最初用於描述大幅或完全整合第三方雲端託管應用程式和服務的應用程式,以管理伺服器端的邏輯和狀態。這些通常是「豐富用戶端」應用程式,例如單頁式網頁應用程式或行動應用程式,它們使用雲端可存取資料庫(例如 Parse、Firebase)、驗證服務(例如 Auth0、AWS Cognito)等廣大的生態系。這些類型的服務以前被稱為「(行動)後端即服務」,在本文的其餘部分,我將使用 「BaaS」 作為簡稱。
  2. 「無伺服器」也可以表示應用程式,其中伺服器端邏輯仍由應用程式開發人員撰寫,但與傳統架構不同的是,它在無狀態運算容器中執行,這些容器由事件觸發、短暫(可能只持續一次呼叫),並由第三方完全管理。一種思考方式是「函式即服務」或 「FaaS」。(注意:這個名稱的原始來源,也就是 @marak 的推文,已不再公開。) AWS Lambda 是目前最受歡迎的函式即服務平台實作之一,但還有許多其他平台。

在本文中,我們將主要關注 FaaS。它不僅是 Serverless 中較新的領域,而且也帶動了許多宣傳,它與我們通常思考技術架構的方式有顯著的差異。

BaaS 和 FaaS 在運作屬性(例如,沒有資源管理)上相關,而且經常一起使用。大型雲端供應商都有「Serverless 組合」,其中包括 BaaS 和 FaaS 產品,例如,以下是 Amazon 的 Serverless 產品頁面。Google 的 Firebase BaaS 資料庫透過 Google Cloud Functions for Firebase 提供明確的 FaaS 支援。

較小的公司也有類似連結這兩個領域的做法。Auth0 從 BaaS 產品開始,實作使用者管理的許多面向,並隨後建立了 FaaS 服務 Webtask。這家公司透過 Extend 進一步實踐這個想法,讓其他 SaaS 和 BaaS 公司可以輕鬆地將 FaaS 功能新增到現有產品,以便他們可以建立統一的 Serverless 產品。

幾個範例

使用者介面驅動的應用程式

讓我們思考一個傳統的三層式客戶導向系統,具備伺服器端邏輯。一個好的範例是一個典型的電子商務應用程式,我敢說是一個線上寵物商店嗎?

傳統上,架構會類似於下方的圖表。假設它在伺服器端以 Java 或 Javascript 實作,並以 HTML + Javascript 元件作為客戶端

使用這個架構,客戶端可以相對地不具備智慧,系統中的大部分邏輯(驗證、頁面導覽、搜尋、交易)都由伺服器應用程式實作。

使用 Serverless 架構,最終可能會更類似於這個樣子

這是一個大幅簡化的檢視,但即使在這裡,我們也看到許多顯著的變更

  1. 我們已刪除原始應用程式中的驗證邏輯,並已用第三方 BaaS 服務(例如,Auth0)取代它。
  2. 使用 BaaS 的另一個範例,我們已允許客戶端直接存取我們的資料庫子集(用於產品清單),而資料庫本身完全由第三方(例如,Google Firebase)託管。我們可能針對以這種方式存取資料庫的客戶端設定不同的安全性設定檔,與存取資料庫的伺服器資源不同。
  3. 前兩個重點暗示了一個非常重要的第三點:寵物商店伺服器中的一些邏輯現在位於客戶端中,例如,追蹤使用者階段、了解應用程式的 UX 結構、從資料庫中讀取並將其轉換為可用的檢視等。客戶端正朝著成為 單頁應用程式 邁進。
  4. 我們可能想要在伺服器中保留一些與 UX 相關的功能,例如,如果它需要大量運算或需要存取大量資料。在我們的寵物商店中,一個範例是「搜尋」。我們可以實作一個 FaaS 函式,透過 API 閘道(稍後說明)回應 HTTP 要求,而不是像原始架構中那樣擁有持續運作的伺服器。客戶端和伺服器「搜尋」函式都從同一個資料庫讀取產品資料。
  5. 如果我們選擇使用 AWS Lambda 作為我們的 FaaS 平台,我們可以將搜尋程式碼從原始的寵物商店伺服器移植到新的寵物商店搜尋功能,而不需要完全重寫,因為 Lambda 支援 Java 和 Javascript,也就是我們原始的實作語言。

  6. 最後,我們可以用另一個獨立的 FaaS 功能取代我們的「購買」功能,選擇將它保留在伺服器端以確保安全性,而不是在客戶端重新實作它。它也由 API 閘道器作為前端。將不同的邏輯需求分解成個別部署的元件,是使用 FaaS 時很常見的做法。

稍微後退一點,這個範例展示了關於無伺服器架構的另一個非常重要的觀點。在原始版本中,所有流程、控制和安全性都由中央伺服器應用程式管理。在無伺服器版本中,沒有這些問題的中央仲裁者。相反地,我們看到偏好編排勝過協調,每個元件扮演更具架構意識的角色,這也是微服務方法中常見的想法。

這種方法有很多好處。正如 Sam Newman 在他的建構微服務一書中所提到的,以這種方式建構的系統通常「更靈活且易於變更」,無論是整體而言或透過元件的獨立更新;有更好的分工;還有一些令人著迷的成本效益,這是 Gojko Adzic 在這場精彩的演講中所討論的重點。

當然,這種設計是一種權衡:它需要更好的分散式監控(稍後會進一步說明),而且我們更仰賴底層平台的安全功能。更根本的是,與我們原本的巨石應用程式相比,有更多需要理解的變動部分。靈活性和成本的優點是否值得增加多個後端元件的複雜性,這取決於實際情況。

訊息驅動的應用程式

另一個範例是後端資料處理服務。

假設你正在撰寫一個以使用者為中心的應用程式,它需要快速回應 UI 要求,其次,它需要擷取所有不同類型的使用者活動,以便後續處理。想想一個線上廣告系統:當使用者點選廣告時,你希望非常快速地將他們重新導向到該廣告的目標。同時,你需要收集點擊已發生的事實,以便你可以向廣告客戶收費。(這個範例並非假設,我在Intent Media的前團隊就有這個需求,他們以無伺服器的方式實作它。)

傳統上,架構可能如下所示。「廣告伺服器」同步回應使用者(未顯示),並將「點擊訊息」發佈到頻道。然後,這個訊息會由「點擊處理器」應用程式非同步處理,它會更新資料庫,例如,減少廣告客戶的預算。

在無伺服器世界中,它看起來如下所示

你能看出差異嗎?與我們的第一個範例相比,這裡的架構變化小得多,這就是為什麼非同步訊息處理是無伺服器技術非常流行的用例。我們用 FaaS 函式取代了長駐訊息使用者應用程式。此函式在供應商提供的事件驅動環境中執行。請注意,雲端平台供應商同時提供訊息代理程式 FaaS 環境,這兩個系統緊密相連。

FaaS 環境也可能透過建立函式程式碼的多個副本來平行處理多則訊息。這可能是一個我們需要考量的新概念,視我們如何撰寫原始流程而定。

解構「功能即服務」

我們已經提到很多 FaaS 了,但現在是深入探討它的真正意義的時候了。為此,讓我們看看 Amazon 的 FaaS 產品 Lambda 的說明。我加入了一些代幣,我將對它們進行說明。

AWS Lambda 讓你可以在不配置或管理伺服器的情況下執行程式碼。(1) ...使用 Lambda,你可以為幾乎任何類型的應用程式或後端服務執行程式碼 (2) - 所有這些都無需管理。只需上傳程式碼,Lambda 就能處理執行 (3) 和擴充 (4) 程式碼所需的一切,並具有高可用性。你可以設定程式碼以自動從其他 AWS 服務觸發 (5) 或直接從任何網頁或行動應用程式呼叫它 (6)

  1. 從根本上來說,FaaS 是關於在不管理自己的伺服器系統或自己的長駐伺服器應用程式的狀況下執行後端程式碼。與其他現代架構趨勢(例如容器和 PaaS(服務平台))相比,第二個子句(長駐伺服器應用程式)是一個關鍵差異。
  2. 如果我們回到前面提到的點擊處理範例,FaaS 會用不需要配置伺服器或始終執行的應用程式來取代點擊處理伺服器(可能是實體機器,但肯定是一個特定的應用程式)。

  3. FaaS 服務不需要編寫特定框架或函式庫的程式碼。FaaS 函式在語言和環境方面是常規應用程式。例如,AWS Lambda 函式可以在 Javascript、Python、Go、任何 JVM 語言(Java、Clojure、Scala 等)或任何 .NET 語言中以「一級」方式實作。但是,Lambda 函式也可以執行與其部署成品綑綁在一起的另一個流程,因此你實際上可以使用任何可以編譯為 Unix 流程的語言(請參閱本文稍後提到的 Apex)。
  4. 不過,FaaS 函式有重大的架構限制,尤其是在狀態和執行時間方面。我們很快就會討論到這一點。

    讓我們再次考慮我們的點擊處理範例。在移轉到 FaaS 時,唯一需要變更的程式碼是「主方法」(啟動)程式碼,因為它已被刪除,而且可能是最上層訊息處理常式的特定程式碼(「訊息監聽器介面」實作),但這可能只是方法簽章的變更。在 FaaS 世界中,其餘程式碼(例如,寫入資料庫的程式碼)沒有什麼不同。

  5. 部署與傳統系統非常不同,因為我們沒有伺服器應用程式要自己執行。在 FaaS 環境中,我們將函式的程式碼上傳到 FaaS 供應商,而供應商會執行配置資源、建立 VM、管理處理程序等所有其他必要工作。
  6. 水平擴充完全自動化、有彈性,並且由供應商管理。如果您的系統需要平行處理 100 個要求,供應商會在您無需執行任何額外設定的情況下處理這些要求。執行函式的「運算容器」是暫時的,FaaS 供應商會根據執行時間需求建立和銷毀它們。最重要的是,透過 FaaS,供應商會處理所有基礎資源配置和分配,使用者完全不需要管理叢集或 VM。
  7. 讓我們回到我們的點擊處理器。假設我們度過美好的一天,而且客戶點擊的廣告數量是平常的十倍。對於傳統架構,我們的點擊處理應用程式能夠處理這件事嗎?例如,我們是否已開發我們的應用程式,讓它能夠一次處理多則訊息?如果我們做到了,應用程式的其中一個執行個體是否足以處理負載?如果我們能夠執行多個處理程序,自動擴充是自動化的,還是我們需要手動重新設定?透過 FaaS 方法,所有這些問題都已經獲得解答,您需要預先撰寫函式,以假設水平擴充的平行性,但從那時起,FaaS 供應商會自動處理所有擴充需求。

  8. FaaS 中的函式通常是由供應商定義的事件類型觸發。對於 Amazon AWS,此類刺激包括 S3(檔案/物件)更新、時間(排程工作),以及新增到訊息匯流排的訊息(例如,Kinesis)。
  9. 大多數供應商也允許函式作為回應入站 HTTP 要求而觸發;在 AWS 中,一般會透過使用 API 閘道來啟用這項功能。我們在寵物商店範例中,為我們的「搜尋」和「購買」函式使用 API 閘道。函式也可以透過平台提供的 API 直接呼叫,不論是外部或來自同一個雲端環境,但這是一種相對不常見的用法。

狀態

在本地(機器/個體繫結)狀態方面,FaaS 函式有顯著的限制,也就是您儲存在記憶體變數中的資料,或您寫入到本地磁碟的資料。您確實有此類儲存空間可用,但您無法保證此類狀態會持續存在於多個呼叫中,更重要的是,您不應該假設函式的一個呼叫狀態會提供給同一個函式的另一個呼叫。因此,FaaS 函式通常被描述為無狀態,但更精確的說法是,需要持續存在的 FaaS 函式狀態,需要外化到 FaaS 函式個體之外。

對於本質上無狀態的 FaaS 函式,也就是說那些提供純粹功能轉換,從輸入到輸出的函式,這一點無關緊要。但對於其他函式,這可能會對應用程式架構產生重大影響,儘管這並非獨特情況,但「十二要素應用程式」概念具有 完全相同的限制。此類以狀態為導向的函式通常會利用資料庫、跨應用程式快取(例如 Redis)或網路檔案/物件儲存(例如 S3)來儲存跨請求的狀態,或提供處理請求所需的進一步輸入。

執行時間

FaaS 函式通常會限制每個呼叫允許執行的時間長度。目前,AWS Lambda 函式回應事件的「逾時」時間最長為五分鐘,然後終止。Microsoft Azure 和 Google Cloud Functions 也有類似的限制。

這表示某些類型的長時間任務不適合 FaaS 函式,除非重新設計架構,否則您可能需要建立數個不同的協調 FaaS 函式,而在傳統環境中,您可能有一個長時間任務執行協調和執行。

啟動延遲和「冷啟動」

FaaS 平台在每個事件之前初始化函式執行個體需要一些時間。此啟動延遲可能會因許多因素而異,即使對於一個特定函式也是如此,範圍可能從幾毫秒到幾秒不等。這聽起來很糟糕,但讓我們更具體一點,以 AWS Lambda 為例。

初始化 Lambda 函式將會是「熱啟動」(重複使用 Lambda 函式執行個體及其主機容器,來自先前的事件)或「冷啟動」(建立新的容器執行個體,啟動函式主機程序等)。毫不意外的是,在考慮啟動延遲時,最令人擔憂的是這些冷啟動。

冷啟動延遲取決於許多變數:您使用的語言、您使用的程式庫數量、您的程式碼有多少、Lambda 函式環境本身的組態、您是否需要連線到 VPC 資源等。其中許多面向都受到開發人員的控制,因此通常可以減少冷啟動過程中產生的啟動延遲。

與冷啟動持續時間一樣,冷啟動頻率也相當多變。例如,如果函式每秒處理 10 個事件,每個事件需要 50 毫秒來處理,則你可能只會在 Lambda 每處理 100,000–200,000 個事件時才會看到冷啟動。另一方面,如果你每小時處理一個事件,則你可能會在每個事件中看到冷啟動,因為 Amazon 會在幾分鐘後停用非活動的 Lambda 執行個體。了解這一點將有助於你了解冷啟動是否會對你造成影響,以及你是否需要執行函式執行個體的「保持運作」以避免它們被淘汰。

冷啟動是否令人擔憂?這取決於你的應用程式的樣式和流量形狀。我在 Intent Media 的前團隊有一個使用 Java(通常是啟動時間最慢的語言)實作的非同步訊息處理 Lambda 應用程式,每天處理數億則訊息,而且他們不擔心此元件的啟動延遲。話雖如此,如果你正在撰寫低延遲交易應用程式,你可能不希望在這個時候使用雲端託管的 FaaS 系統,無論你使用哪種語言來實作。

無論你是否認為你的應用程式可能有此類問題,你都應該使用類似的生產負載來測試效能。如果你的使用案例現在無法運作,你可能需要在幾個月後再試一次,因為這是 FaaS 供應商持續改進的主要領域。

有關冷啟動的更多詳細資訊,請參閱我關於此主題的文章

API 閘道

我們先前討論過的無伺服器的一個面向是「API 閘道」。API 閘道是一個 HTTP 伺服器,其中路由和端點在組態中定義,每個路由都與處理該路由的資源相關聯。在無伺服器架構中,此類處理常式是 FaaS 函式。

當 API 閘道收到請求時,它會找到與請求相符的路由組態,並且在 FaaS 支援的路由的情況下,會使用原始請求的表示呼叫相關的 FaaS 函式。通常,API 閘道會允許將 HTTP 請求參數對應到 FaaS 函式的更簡潔輸入,或者允許傳遞整個 HTTP 請求,通常作為 JSON 物件。FaaS 函式會執行其邏輯並將結果傳回 API 閘道,然後 API 閘道會將此結果轉換為 HTTP 回應,並將其傳遞回原始呼叫者。

Amazon Web Services 有自己的 API 閘道(名稱有點令人困惑,稱為「API Gateway」),其他供應商也提供類似的功能。Amazon 的 API Gateway 本身就是一項 BaaS(沒錯,就是 BaaS!)服務,因為它是一項外部服務,您可以進行設定,但不需要自行執行或提供。

除了純粹路由要求之外,API 閘道也可以執行驗證、輸入驗證、回應代碼對應等更多功能。(如果您在思考這是否真的這麼好的主意時,您的蜘蛛感應開始作動,請暫停這個念頭!我們稍後會進一步探討這一點。)

API 閘道與 FaaS 函數搭配使用的一個用例,是以無伺服器的方式建立 HTTP 前端微服務,並享有 FaaS 函數帶來的所有擴充、管理和其他好處。

當我第一次撰寫這篇文章時,至少 Amazon 的 API Gateway 的工具令人痛心地不成熟。從那時起,這些工具已經有了顯著的改善。AWS API Gateway 等元件並非「主流」,但希望它們比以前好一點,而且只會持續改善。

工具

上述關於工具成熟度的評論也適用於一般的無伺服器 FaaS。2016 年時情況相當糟糕;到了 2018 年,我們已經看到明顯的改善,而且我們預期工具會變得更好。

在 FaaS 世界中,值得一提的幾個良好的「開發人員 UX」範例。首先是 Auth0 Webtask,它在其工具中非常重視開發人員 UX。其次是 Microsoft,以及他們的 Azure Functions 產品。Microsoft 一直將 Visual Studio 及其緊密的回饋迴路放在其開發人員產品的最前線,而 Azure Functions 也不例外。它提供在雲端觸發的事件中輸入,在本地除錯函數的能力相當特別。

仍然需要顯著改善的領域是監控。我稍後會討論這一點。

開源

到目前為止,我主要討論專有供應商產品和工具。大多數無伺服器應用程式都會使用這些服務,但這個世界上也有開源專案。

無伺服器中開源最常見的用途是 FaaS 工具和架構,特別是廣受歡迎的 Serverless Framework,它旨在讓使用 AWS API Gateway 和 Lambda 比使用 AWS 提供的工具更容易。它還提供一定程度的跨供應商工具抽象,有些使用者認為這很有價值。類似工具的範例包括 ClaudiaZappa。另一個範例是 Apex,它特別有趣,因為它允許您使用 Amazon 直接支援以外的語言來開發 Lambda 函數。

不過,大型供應商本身並未在開源工具派對中落後。AWS 自家的部署工具 SAM(無伺服器應用程式模型也是開源的

專有 FaaS 的主要好處之一是不必擔心底層運算基礎架構(機器、VM,甚至容器)。但是,如果您想要擔心這些事情呢?也許您有一些雲端供應商無法滿足的安全需求,或者您已經購買了幾組伺服器,而且不想丟掉。在這些情況下,開源是否有幫助,讓您可以執行自己的「有伺服器」FaaS 平台?

是的,而且在這個領域中已經有許多活動。開放原始碼 FaaS 的初期領導者之一是 IBM(透過 OpenWhisk,現在是 Apache 專案),而令人驚訝的是,還有 Microsoft,它開放了大部分的 Azure Functions 平台。許多其他自架式 FaaS 實作會使用底層容器平台,通常是 Kubernetes,這在許多方面來說都很合理。在這個領域中,值得探索的專案包括 Galactic FogFissionOpenFaaS。這是一個龐大且快速變動的世界,我建議查看 Cloud Native Computing Federation (CNCF) 無伺服器工作小組 所做的追蹤工作。

什麼不是無伺服器?

到目前為止,我在本文中將無伺服器描述為兩個概念的結合:後端即服務和功能即服務。我也深入探討了後者的功能。關於我認為無伺服器服務的主要屬性(以及為何我認為像 S3 這樣更舊的服務也是無伺服器)的更精確說明,請參閱我的另一篇文章:定義無伺服器

在我們開始探討非常重要的優缺點領域之前,我想再花一點時間來定義。讓我們定義無伺服器是什麼。

與 PaaS 的比較

由於無伺服器 FaaS 功能與 十二要素應用程式 非常類似,它們是否只是 "平台即服務" (PaaS) 的另一種形式,例如 Heroku?對於簡短的回答,我引用 Adrian Cockcroft

如果您的 PaaS 能夠在 20 毫秒內有效啟動執行半秒的執行個體,那麼就稱它為無伺服器。

-- Adrian Cockcroft

換句話說,大多數 PaaS 應用程式並非針對在事件發生時啟動和關閉整個應用程式,而 FaaS 平台則會完全執行此動作。

如果我是一位優秀的十二要素應用程式開發人員,這不一定要影響我編寫程式和設計應用程式的模式,但它確實會對我操作應用程式的模式造成很大的影響。由於我們都是優秀的 DevOps 工程師,我們思考營運的程度與思考開發的程度一樣多,對吧?

FaaS 與 PaaS 之間的主要運作差異在於擴充。通常使用 PaaS 時,您仍需要思考如何擴充,例如使用 Heroku 時,您想要執行多少個 Dyno?使用 FaaS 應用程式時,這完全是透明的。即使您設定 PaaS 應用程式自動擴充,您也不會針對個別要求執行此操作(除非您的流量特徵非常具體),因此在成本方面,FaaS 應用程式更有效率。

有此優點,您為何仍要使用 PaaS?原因有幾個,但工具可能是最大的原因。此外,有些人使用 PaaS 平台,例如 Cloud Foundry,以提供跨混合式公有雲和私有雲的共通開發體驗;撰寫本文時,沒有 FaaS 相當成熟的技術。

與容器的比較

使用無伺服器 FaaS 的原因之一是避免在作業系統層級管理應用程式程序。PaaS 服務(例如 Heroku)也提供此功能,我已在上面說明 PaaS 與無伺服器 FaaS 的差異。程序的另一個流行抽象化是容器,Docker 是此類技術最明顯的範例。容器主機系統(例如 MesosKubernetes),可將個別應用程式從作業系統層級部署抽象化,越來越受歡迎。在此路徑上,我們看到雲端主機容器平台,例如 Amazon ECSEKS,以及 Google Container Engine,這些平台與無伺服器 FaaS 類似,讓團隊完全避免管理自己的伺服器主機。考量到容器的發展趨勢,無伺服器 FaaS 是否仍值得考慮?

我對 PaaS 提出的論點,在容器方面仍然成立 - 對於無伺服器 FaaS,擴充會自動管理、透明且細緻,這與我先前提到的自動資源配置和分配有關。傳統上,容器平台仍需要您管理叢集的大小和形狀。

我也認為容器技術仍不成熟且不穩定,儘管它越來越接近成熟。當然,這並不是說無伺服器 FaaS 已成熟,但挑選您想要的粗糙邊緣仍然是當務之急。

另外,值得一提的是,現在容器平台中已提供自動縮放容器叢集。Kubernetes 已內建此功能,並附有「水平 Pod 自動縮放」,而 AWS Fargate 等服務也承諾提供「無伺服器容器」。

隨著我們看到無伺服器 FaaS 與託管容器之間的管理和縮放差距縮小,它們之間的選擇可能只取決於應用程式的風格和類型。例如,FaaS 可能被視為事件驅動型風格的較佳選擇,每個應用程式元件的事件類型較少,而容器則被視為具有多個進入點的同步請求驅動型元件的較佳選擇。我預期在相當短的時間內,許多應用程式和團隊將同時使用這兩種架構方法,而看到此類使用模式的出現將會非常有趣。

#NoOps

無伺服器並不表示「無作業」—儘管它可能表示「無系統管理員」,具體取決於您深入無伺服器領域的程度。

「作業」的意義遠超過伺服器管理。它至少也包含監控、部署、安全性、網路、支援,以及通常一定程度的製作除錯和系統縮放。這些問題在無伺服器應用程式中仍然存在,而且您仍然需要一個策略來處理它們。在某些方面,在無伺服器世界中,作業更困難,因為其中許多都是如此新穎。

系統管理員仍然存在—您只是透過無伺服器將其外包出去。這不一定是壞事(或好事)—我們外包了很多事情,而它的好壞取決於您確切嘗試執行什麼。無論如何,在某個時間點,抽象化可能會外洩,而您需要知道某處有人類系統管理員在支援您的應用程式。

Charity Majors 在第一屆 Serverlessconf 上就這個主題發表了精彩演講。(您也可以閱讀她的兩篇相關文章:什麼是作業?作業最佳實務。)

儲存程序即服務

我想知道無伺服器服務是否會變成像儲存程序一樣,一個好主意卻迅速變成龐大的技術債務

-- Camille Fournier

我見過另一個主題是,無伺服器 FaaS 是「資料庫即服務」。我認為這是因為許多 FaaS 函數範例(包括我在本文中使用的一些範例)都是與資料庫緊密整合的小型程式碼片段。如果 FaaS 的用途僅限於此,那麼這個名稱會很有用,但由於這只是 FaaS 功能的一小部分,因此我不認為用這些術語來思考 FaaS 會很有用。

話雖如此,值得考慮的是,FaaS 是否會伴隨著一些與儲存程序相同的問題,包括 Camille 在上述推文中提到的技術負債問題。使用儲存程序可以獲得許多教訓,這些教訓值得在 FaaS 的背景下進行檢視,並了解它們是否適用。請考慮儲存程序

  1. 通常需要供應商特定的語言,或至少是供應商特定的架構/語言擴充功能
  2. 由於需要在資料庫的背景下執行,因此很難進行測試
  3. 很難進行版本控制或將其視為一級應用程式

雖然這些問題不一定會適用於儲存程序的所有實作,但它們肯定會遇到一些問題。讓我們看看它們是否適用於 FaaS

到目前為止,(1) 肯定不是我所見過 FaaS 實作的問題,所以我們可以立即將其從清單中刪除。

對於 (2),由於我們處理的是「純程式碼」,因此單元測試絕對像其他程式碼一樣容易。整合測試是一個不同的(且合法的)問題,我們稍後會討論。

對於 (3),由於 FaaS 函數又是「純程式碼」,因此版本控制沒問題。直到最近,應用程式封裝也是一個問題,但我們開始在此處看到成熟度,例如 Amazon 的 無伺服器應用程式模型 (SAM) 和我之前提到的無伺服器架構。在 2018 年初,Amazon 甚至推出了「無伺服器應用程式儲存庫」(SAR),為組織提供一種在 AWS 無伺服器服務上建置應用程式和應用程式元件的方法。(在我的標題為 檢視 AWS 無伺服器應用程式儲存庫 的文章中,進一步了解 SAR。)

好處

到目前為止,我主要試圖堅持定義和說明無伺服器架構的含義。現在,我將討論這種設計和部署應用程式的優缺點。在沒有仔細考慮並權衡利弊的情況下,你絕對不應該做出使用無伺服器的任何決定。

讓我們從彩虹和獨角獸的國度開始,看看無伺服器的優點。

降低營運成本

無伺服器在最簡單的情況下,是一種外包解決方案。它允許你付費給某人來管理伺服器、資料庫,甚至是你可能自己管理的應用程式邏輯。由於你使用的是許多其他人也會使用的預定義服務,因此我們會看到規模經濟效應:你為受管理資料庫支付的費用較低,因為一個供應商正在執行數千個非常相似的資料庫。

降低的成本對你來說會顯示為兩個方面的總和。第一個是基礎設施成本收益,這純粹來自與其他人共享基礎設施(例如,硬體、網路)。第二個是勞動力成本收益:你將能夠在外包的無伺服器系統上花費比自己開發和託管的等效系統更少的時間。

然而,此好處與你從基礎設施即服務 (IaaS) 或平台即服務 (PaaS) 中獲得的好處沒有太大不同。但我們可以通過兩種關鍵方式來擴展此好處,每種方式分別適用於無伺服器 BaaS 和 FaaS。

BaaS:降低開發成本

IaaS 和 PaaS 基於伺服器和作業系統管理可以商品化的前提。另一方面,無伺服器後端即服務是整個應用程式組件商品化的結果。

驗證是一個很好的例子。許多應用程式編寫自己的驗證功能,其中通常包括註冊、登入、密碼管理以及與其他驗證提供者整合等功能。總的來說,這個邏輯在大多數應用程式中非常相似,而像Auth0這樣的服務已被建立,允許我們將現成的驗證功能整合到我們的應用程式中,而無需自己開發。

在同一個執行緒上的是 BaaS 資料庫,例如Firebase 的資料庫服務。一些行動應用程式團隊發現讓客戶端直接與伺服器端資料庫通訊是有意義的。BaaS 資料庫消除了大部分資料庫管理開銷,並且通常提供機制來對不同類型的使用者執行適當的授權,符合無伺服器應用程式的預期模式。

根據你的背景,這些想法可能會讓你感到不安(可能是因為我們將在缺點部分中討論的原因),但不可否認的是,許多成功的公司已經能夠生產出幾乎沒有自己的伺服器端程式碼的引人注目的產品。喬·艾米森在第一次無伺服器大會上舉了幾個例子

FaaS:擴充成本

無伺服器 FaaS 的樂趣之一在於——正如我在本文前面所說的那樣——「水平擴充是完全自動、彈性的,並且由提供者管理。」這有幾個好處,但在基本的基礎設施方面,最大的好處是你只為你需要的運算付費,在 AWS Lambda 的情況下,低至 100 毫秒的界線。根據你的流量規模和形狀,這對你來說可能是一個巨大的經濟收益。

範例:偶發請求

假設你正在執行一個伺服器應用程式,它每分鐘只處理一個請求,處理每個請求需要 50 毫秒,而你在一個小時內的平均 CPU 使用率為 0.1%。如果這個應用程式部署到它自己的專用主機,那麼這將非常低效率。一千個其他類似的應用程式都可以共享那台機器。

無伺服器 FaaS 捕捉此項低效率,以降低成本的形式將好處傳遞給您。使用上述範例應用程式,您每分鐘只需支付 100 毫秒的運算費用,約為整體時間的 0.15%。

這具有以下連帶好處

  • 對於負載需求非常小的準微服務,即使此類精細粒度的營運成本可能原本過於高昂,它也能支援依據邏輯/網域來分解元件。
  • 此類成本效益是絕佳的民主化工具。如果公司或團隊想要嘗試新事物,當他們使用 FaaS 來滿足其運算需求時,與「踏入水中」相關的營運成本極低。事實上,如果您的總工作負載相對較小(但並非完全不重要),您可能完全不需要支付任何運算費用,因為有些 FaaS 供應商提供「免費層級」。

範例:不穩定的流量

我們來看另一個範例。假設您的流量模式非常尖峰,您的基準流量可能是每秒 20 個要求,但每五分鐘您會收到每秒 200 個要求(是平常數量的 10 倍),持續 10 秒。為了範例起見,我們也假設您的基準效能已將您偏好的主機伺服器類型發揮到極致,而且您不希望在流量尖峰階段降低您的回應時間。您要如何解決這個問題?

在傳統環境中,您可能需要將您的總硬體數量增加 10 倍,以處理尖峰,即使尖峰的總持續時間不到機器總上線時間的 4%。由於新伺服器執行個體啟動所需的時間,自動調整大小可能不是一個好選項,因為當您的新執行個體啟動時,尖峰階段已經結束了。

然而,使用無伺服器 FaaS,這將不再是問題。您實際上與您的流量模式一致時沒有什麼不同,而且您只需在尖峰階段支付額外的運算容量費用。

很明顯地,我已經刻意挑選了幾個範例,其中無伺服器 FaaS 可帶來巨大的成本節省,但重點是要說明,從擴展觀點來看,除非您的流量形狀非常穩定,持續使用伺服器主機的全部容量,否則使用 FaaS 就能省錢。

關於上述內容的一個注意事項:如果您的流量是均勻的,並且會持續充分利用正在執行的伺服器,您可能看不到這種成本效益,而且實際上使用 FaaS 可能會花費更多。您應該做一些計算,並將目前的供應商成本與執行全時伺服器的成本等值進行比較,以了解成本是否可接受。

有關 FaaS 成本效益的更多詳細資訊,我推薦 Gojko Adzic 和 Robert Chatley 撰寫的論文「無伺服器運算:經濟和架構影響」。

最佳化是部分成本節省的根本

關於 FaaS 成本,還有一個值得一提的有趣面向:對程式碼所做的任何效能最佳化,不僅會增加應用程式的速度,而且會直接且立即連結到營運成本的降低,具體取決於供應商計費方案的詳細程度。例如,假設一個應用程式最初需要一秒鐘來處理一個事件。如果透過程式碼最佳化,將其減少到 200 毫秒,它將(在 AWS Lambda 上)立即看到運算成本節省 80%,而無需進行任何基礎架構變更。

簡化營運管理

下一段附帶一個巨大的星號符號——某些營運面向對無伺服器來說仍然很困難,但目前我們仍堅持我們的獨角獸和彩虹朋友…

在無伺服器 BaaS 的那一邊,很明顯地,為什麼營運管理比其他架構更簡單:支援較少的元件等於工作較少。

在 FaaS 的那一邊,有許多面向在發揮作用,我將深入探討其中幾個。

FaaS 的擴充優點超越基礎設施成本

雖然擴展在我們腦海中從上一段仍然很新鮮,但值得注意的是,FaaS 的擴展功能不僅降低了運算成本,還降低了營運管理,因為擴展是自動化的。

在最佳情況下,如果您的擴展程序是手動的——例如,人類需要明確地將執行個體新增和移除到伺服器陣列——使用 FaaS,您可以愉快地忘記它,讓您的 FaaS 供應商為您擴展應用程式。

即使您已經開始在非 FaaS 架構中使用自動調整,這仍然需要設定和維護。使用 FaaS 後,這項工作不再需要。

類似地,由於調整是由供應商在每個請求/事件中執行,您不再需要考慮在記憶體用盡或效能受到過多影響之前,可以處理多少並行請求——至少在您的 FaaS 托管元件中不需要。下游資料庫和非 FaaS 元件必須重新考量,因為其負載可能會大幅增加。

降低封裝和部署的複雜性

與部署整個伺服器相比,封裝和部署 FaaS 函式很簡單。您所做的就是將所有程式碼封裝成一個 zip 檔案,然後上傳。沒有 Puppet/Chef,沒有啟動/停止 shell 指令碼,沒有關於是否在機器上部署一個或多個容器的決策。如果您只是剛開始,您甚至不需要封裝任何東西——您可以在供應商主控台中撰寫您的程式碼(顯然,不建議將此用於生產程式碼!)。

這個過程不需要花很長時間來描述,但對於某些團隊來說,這個好處可能非常巨大:一個完全無伺服器的解決方案不需要任何系統管理

PaaS 解決方案有類似的部署好處,但正如我們之前所見,在將 PaaS 與 FaaS 進行比較時,調整優勢是 FaaS 獨有的。

縮短上市時間和持續實驗

更簡單的操作管理是我們作為工程師所理解的好處,但這對我們的業務來說是什麼意思?

顯而易見的原因是成本:花在營運上的時間越少,就表示需要的人力越少,正如我已經描述的那樣。但在我看來,一個更重要的原因是上市時間。隨著我們的團隊和產品越來越傾向於精實和敏捷的流程,我們希望不斷嘗試新事物並快速更新現有系統。雖然在持續交付的背景下進行簡單的重新部署允許對穩定專案進行快速反覆運算,但擁有良好的新想法到初始部署能力使我們能夠以低摩擦和最低成本嘗試新的實驗。

對於 FaaS 來說,新想法到初始部署的故事通常很出色,特別是對於由供應商生態系統中定義成熟的事件觸發的簡單函式。例如,假設您的組織已經使用AWS Kinesis,一個類似 Kafka 的訊息系統,透過您的基礎架構廣播各種類型的即時事件。使用 AWS Lambda,您可以在幾分鐘內針對該 Kinesis 串流開發和部署新的生產事件偵聽器——您可以在一天內嘗試多個不同的實驗!

雖然成本效益是無伺服器最容易表達的改進,但最讓我興奮的是交貨時間的縮短。它可以實現產品開發思維的 持續實驗,這對我們在公司中交付軟體的方式來說是一場真正的革命。

「更環保」的運算?

在過去的幾十年中,全球資料中心數量和規模大幅增加。除了建立這些中心所需的實體資源外,相關的能源需求非常龐大,以至於 Apple、Google 等公司討論將部分資料中心設在可再生能源附近,以減少此類場址燃燒化石燃料的影響,否則這些場址將是必要的。

閒置但通電的伺服器會消耗大量的能源,而且它們是我們需要如此多且更大的資料中心的主要原因

企業和企業資料中心中的典型伺服器在全年平均提供其最大運算輸出的 5% 到 15%。

-- 富比士

這非常低效,而且會造成巨大的環境影響。

一方面,雲端基礎設施可能已經有助於減少這種影響,因為公司可以「依需求」購買更多伺服器,僅在絕對需要時購買,而不是長時間預先配置所有可能需要的伺服器。然而,有人也可能會辯稱,如果許多伺服器在沒有適當容量管理的情況下被閒置,那麼配置伺服器的容易性可能會使情況惡化。

無論我們使用自架主機伺服器、IaaS 或 PaaS 基礎設施解決方案,我們仍然會手動對我們的應用程式做出容量決策,而這些決策通常會持續數月或數年。通常,我們在管理容量時會謹慎行事,這是正確的,因此我們會過度配置,導致剛剛描述的低效率。透過無伺服器方法,我們不再自己做出此類容量決策,我們讓無伺服器供應商根據我們的需求即時配置足夠的運算容量。然後,供應商可以根據其客戶的總體情況做出自己的容量決策。

這種差異應該會導致資料中心更有效率地使用資源,因此與傳統的容量管理方法相比,可以減少環境影響。

缺點

所以,親愛的讀者,我希望你享受在彩虹、獨角獸和所有閃亮美好的事物中的時光,因為我們即將被現實的濕魚打臉。

無伺服器架構肯定有許多優點,但它們也伴隨著顯著的權衡取捨。其中一些權衡取捨是概念固有的;它們無法完全透過進度來修正,而且始終需要考量。其他則與目前的實作有關;隨著時間推移,我們可以預期看到這些問題得到解決。

固有缺點

供應商控制

使用任何外包策略,你都將放棄系統的部分控制權給第三方供應商。這種缺乏控制可能會表現為系統停機、意外限制、成本變更、功能損失、強制 API 升級,以及更多問題。我先前提到的 Charity Majors 在這篇文章的權衡取捨部分中更詳細地說明了這個問題。

[供應商服務] 如果很聰明,將會對你可以如何使用它施加嚴格的限制,因此它們更有可能實現其可靠性目標。當使用者有彈性和選擇時,就會造成混亂和不可靠。如果平台必須在你與其他數千名客戶的快樂之間做出選擇,他們每次都會選擇多數而非少數,這是他們應該做的。

-- Charity Majors

多租戶問題

多租戶是指多個不同客戶(或租戶)的軟體多個執行個體在同一台機器上執行,而且可能在同一個 hosting 應用程式中執行。這是一種實現我們先前提到的規模經濟效益的策略。服務供應商盡其所能讓客戶覺得他們是唯一使用其系統的人,而且通常好的服務供應商都能做得很好。但沒有人完美無缺,有時多租戶解決方案會在安全性(一個客戶能夠看到另一個客戶的資料)、穩健性(一個客戶軟體中的錯誤導致另一個客戶軟體發生故障)和效能(高負載客戶導致另一個客戶速度變慢)方面出現問題。

這些問題並非僅限於無伺服器系統,它們存在於許多其他使用多租戶服務的服務中。AWS Lambda 現在已經夠成熟,我們預期不會看到這些問題,但您應該注意任何較不成熟的服務中此類問題,無論是來自 AWS 或其他供應商。

供應商鎖定

您從一個供應商使用的任何無伺服器功能都極有可能會由另一個供應商以不同的方式實作。如果您想要切換供應商,您幾乎肯定需要更新您的操作工具(部署、監控等),您可能需要變更您的程式碼(例如,以滿足不同的 FaaS 介面),如果您有競爭供應商實作行為的差異,您甚至可能需要變更您的設計或架構。

即使您設法輕鬆地遷移生態系統的一部分,您可能會受到另一個架構元件的更大影響。例如,假設您使用 AWS Lambda 來回應 AWS Kinesis 訊息匯流排上的事件。之間的差異 AWS LambdaGoogle Cloud FunctionsMicrosoft Azure Functions 可能相對較小,但您仍然無法將後兩個供應商實作直接連接到您的 AWS Kinesis 串流。這表示從一個解決方案搬移或移植您的程式碼到另一個解決方案是不可能的,除非也搬移您的基礎架構的其他區塊

許多人害怕這個想法,知道如果您今天選擇的雲端供應商明天需要變更,您必須做很多工作,這並非很棒的感覺。由於這個原因,有些人採用「多雲端」方法,以與實際使用的雲端供應商無關的方式開發和操作應用程式。這通常比單一雲端方法更昂貴,因此雖然供應商鎖定是一個合理的疑慮,但我仍然建議選擇一個讓您滿意的供應商,並盡可能地利用其功能。我在 這篇文章 中進一步說明原因。

安全性疑慮

採用無伺服器方法會讓您面臨許多安全性問題。以下僅列出一些需要考慮的事項,務必探討其他可能影響您的事項。

  • 您使用的每個無伺服器供應商都會增加生態系統採用的不同安全性實作數量。這會增加惡意意圖的表面積,並提高攻擊成功的可能性。
  • 如果您直接從行動平台使用 BaaS 資料庫,您會失去傳統應用程式中伺服器端應用程式提供的保護屏障。雖然這並非不可接受,但確實需要在設計和開發應用程式時特別小心。
  • 當您的組織採用 FaaS 時,您可能會在公司內部遇到 FaaS 函數的寒武紀大爆發。每個函數都會帶來另一個問題媒介。例如,在 AWS Lambda 中,每個 Lambda 函數通常都與設定的 IAM 政策 密不可分,而這很容易出錯。這不是一個簡單的主題,也不是可以忽略的主題。IAM 管理需要仔細考量,至少在 AWS 生產帳戶中是如此。

重複不同客戶端平台的邏輯

使用「完整」BaaS 架構時,伺服器端不會撰寫自訂邏輯,所有邏輯都在客戶端中。這對於您的第一個客戶端平台來說可能很好,但只要您需要下一個平台,您就需要重複實作該邏輯的子集,而您在更傳統的架構中不需要重複執行此操作。例如,如果在此類系統中使用 BaaS 資料庫,您現在的所有客戶端應用程式(可能是網頁、原生 iOS 和原生 Android)都需要能夠與您的供應商資料庫進行通訊,並且需要了解如何從您的資料庫架構對應到應用程式邏輯。

此外,如果您想要在任何時間點移轉到新的資料庫,您需要在所有不同的客戶端中複製該編碼/協調變更。

失去伺服器最佳化

使用完整的 BaaS 架構時,沒有機會針對客戶端效能最佳化您的伺服器設計。 「後端到前端」 模式存在於伺服器中抽象化整個系統的特定基礎面向,部分原因是讓客戶端可以執行作業更快速,並在行動應用程式的案例中使用較少的電池電量。完整的 BaaS 無法使用此類模式。

對於所有自訂邏輯都在客戶端,而後端服務僅由供應商提供的完整 BaaS 架構,這項缺點和前一項缺點都存在。要減輕這兩個缺點的方法是採用 FaaS 或其他類型的輕量級伺服器端模式,將特定邏輯移到伺服器。

無伺服器 FaaS 沒有伺服器內部狀態

在討論過幾個 BaaS 特定的缺點後,我們來談談 FaaS。我先前提到

FaaS 函式在處理本機狀態時有嚴格的限制。..您不應假設函式的一次呼叫狀態會提供給該函式的另一次呼叫。

此假設的理由是,對於 FaaS,我們通常無法控制函式主機容器的啟動和停止時間。

我先前也提到,本機狀態的替代方案是遵循十二要素應用程式的要素編號 6,也就是接受此限制

十二要素程序是無狀態且不共用任何資源的。任何需要持續存在的資料都必須儲存在有狀態後援服務中,通常是資料庫。

-- 十二要素應用程式

Heroku 建議採用這種思考方式,但由於您可以控制 Heroku Dynos 的啟動和停止時間,因此在他們的 PaaS 上執行時可以調整規則。對於 FaaS,則無法調整規則。

因此,如果您無法將狀態保留在記憶體中,FaaS 的狀態會到哪裡去?上述引文提到使用資料庫,在許多情況下,快速的 NoSQL 資料庫、非程序快取(例如 Redis)或外部物件/檔案儲存(例如 S3)會是您的部分選項。但這些都比記憶體中或機器內持續性慢很多。您需要考慮您的應用程式是否適合這樣做。

這方面的另一個考量是記憶體中快取。許多從外部儲存的大型資料集讀取的應用程式會保留該資料集部分的記憶體中快取。您可能會從資料庫的「參考資料」表格讀取,並使用類似 Ehcache 的東西。或者,您可能會從指定快取標頭的 HTTP 服務讀取,在這種情況下,您的記憶體中 HTTP 客戶端可以提供本機快取。

FaaS 允許使用一些本機快取,這可能很有用,假設您的函式使用頻率夠高。例如,對於 AWS Lambda,我們通常預期函式執行個體會持續存在幾個小時,只要每隔幾分鐘使用一次即可。這表示我們可以使用 Lambda 可以提供的(可設定)3 GB RAM 或 512 MB 本機「/tmp」空間。對於某些快取,這可能就夠了。否則,您將不再需要假設程序內快取,而且您需要使用低延遲外部快取,例如 Redis 或 Memcached。然而,這需要額外的作業,而且視您的使用案例而定,可能會慢到無法接受。

實作缺點

先前所述的缺點可能永遠存在於無伺服器中。我們將看到改善緩解方案,但它們永遠存在。

然而,其餘的缺點純粹歸因於當前的技術水準。只要供應商和/或英雄社群願意投入心力,這些缺點都能夠被消除。事實上,自本文第一個版本以來,此清單已經縮短。

組態

當我撰寫本文的第一個版本時,AWS 在 Lambda 函式的設定方面提供的協助非常有限。我很高興地說,現在這個問題已經解決了,但如果你使用較不成熟的平台,這仍然是值得檢查的事情。

自己執行 DoS

以下是一個範例,說明為什麼在你處理 FaaS 時,「買者自負」是一個關鍵詞。AWS Lambda 限制在給定的時間內可以同時執行多少個 Lambda 函式。假設這個限制是一千個;這表示在任何時間,你都可以執行一千個函式實例。如果你需要超過這個數量,你可能會開始收到例外狀況、排隊和/或一般的速度變慢。

這裡的問題是,這個限制適用於整個 AWS 帳戶。有些組織將同一個 AWS 帳戶用於生產和測試。這表示如果組織中的某個人在某個地方執行新的負載測試,並開始嘗試執行一千個並行的 Lambda 函式,你會意外地對你的生產應用程式執行 DoS 攻擊。糟糕。

即使你為生產和開發使用不同的 AWS 帳戶,一個超載的生產 lambda(例如,處理來自客戶的批次上傳)也可能導致你獨立的即時 lambda 後端生產 API 沒有回應。

Amazon 在這裡提供了一些保護,透過保留並行性。保留並行性允許你限制 Lambda 函式的並行性,這樣它就不會炸毀你帳戶的其餘部分,同時確保無論帳戶中的其他函式在做什麼,總是有可用的容量。然而,保留並行性並未預設為帳戶開啟,而且需要小心管理。

執行時間

本文前面提到,如果 AWS Lambda 函式執行超過五分鐘,就會中止。這已經持續了好幾年,AWS 沒有顯示出任何要改變它的跡象。

啟動延遲

我稍早討論過冷啟動,並提到 我針對此主題的文章。AWS 已經隨著時間改善這個領域,但仍有許多重大的疑慮,特別是對於僅偶爾觸發的 JVM 實作函式和/或需要存取 VPC 資源的函式。預期這個領域將持續改善。

好的,針對 AWS Lambda 的挑剔就到此為止。我確定其他供應商也有一些難看的秘密,只是藏得很好。

測試

單元測試無伺服器應用程式相當簡單,原因是我稍早提過的:您撰寫的任何程式碼都是「純程式碼」,而且大部分情況下,您不需要使用許多自訂函式庫或實作介面。

另一方面,整合測試無伺服器應用程式很困難。在 BaaS 世界中,您刻意依賴外部提供的系統,而不是自己的資料庫。因此,您的整合測試是否也應該使用外部系統?如果是,那麼這些系統對於測試情境有多友善?您能輕鬆建立和移除狀態嗎?您的供應商能為您提供不同的負載測試計費策略嗎?

如果您想在整合測試中存根這些外部系統,供應商是否提供本機存根模擬?如果是,存根的保真度有多高?如果供應商未提供存根,您將如何自己實作一個?

FaaS 領域中存在相同的問題,儘管這個領域已經有所改善。現在可以在本機執行 FaaS 函式,適用於 Lambda 和 Microsoft Azure。然而,沒有任何本機環境可以完全模擬雲端環境;我並不建議單獨依賴本機 FaaS 環境。事實上,我更進一步建議,您執行自動化整合測試的正規環境(至少作為 部署管線 的一部分)應該是雲端,而且您應該主要將本機測試環境用於互動式開發和除錯。這些本機測試環境持續改善 - 例如,SAM CLI 提供快速回饋,用於開發 Lambda 支援的 HTTP API 應用程式。

還記得我在幾節前提到的跨帳戶執行限制嗎?當在雲端執行整合測試時。您可能至少想將此類測試與您的生產雲端帳戶隔離,甚至可能使用更細緻的帳戶。

考量整合測試之所以會成為一大問題,部分原因在於我們與無伺服器 FaaS 整合的單位(也就是每個函式)比其他架構小很多,因此我們比其他架構樣式更依賴整合測試。

仰賴雲端測試環境,而非在筆電上本地執行所有內容,對我來說相當震撼。但時代在變,我們從雲端獲得的功能與 Google 等工程師十多年來擁有的類似。Amazon 現在甚至讓您在雲端執行 IDE。我還沒完全做到這一點,但這很可能會發生。

偵錯

使用 FaaS 除錯是一個有趣的領域。這方面已經有進展,主要與在本地執行 FaaS 函式有關,符合上述討論的測試更新。正如我先前所提,Microsoft 提供絕佳的除錯支援,用於在本地執行的函式,但由遠端事件觸發。Amazon 提供類似功能,但尚未由生產事件觸發。

除錯實際在生產雲端環境中執行的函式是另一回事。至少 Lambda 目前不支援這一點,儘管看到這種功能會很棒。

部署、封裝和版本控制

這是一個積極改善的領域。AWS 在改善此領域方面已取得長足進展,稍後我將在「無伺服器的未來」部分進一步討論。

發現

發現」是微服務世界中經常討論的主題:一個服務如何呼叫另一個服務的正確版本。在無伺服器世界中,很少討論發現。這最初讓我擔心,但現在我比較不擔心了。無伺服器的許多用法本質上都是事件驅動的,而這裡事件的使用者通常會在某種程度上自我註冊。對於 FaaS 的 API 導向用法,我們通常在 API 閘道之後使用它們。在此背景下,我們在 API 閘道之前使用 DNS,並在閘道之後進行自動化部署/流量轉移。我們甚至可以在 API 閘道之前使用更多層(例如使用AWS CloudFront)來支援跨區域復原能力。

我將這個想法留在「限制」中,因為我不認為它已被證實,但最終它可能會沒問題。

監控和可觀察性

監控是 FaaS 的一個棘手領域,因為容器的本質是短暫的。大多數雲端供應商都會提供一定程度的監控支援,我們也看到許多傳統監控供應商在此方面進行許多第三方工作。儘管如此,他們和您最終能做什麼,取決於供應商提供的基本資料。在某些情況下這可能沒問題,但至少對於 AWS Lambda 來說,這是非常基本的。我們在此領域真正需要的是開放 API 和第三方服務提供更多協助的能力。

API 閘道定義和過於雄心勃勃的 API 閘道

Thoughtworks 在其技術雷達出版物中討論了 過於雄心勃勃的 API 閘道。雖然連結一般是指 API 閘道(例如,對於那些傳統部署微服務的閘道),但它絕對可以套用於將 API 閘道用作 HTTP 前端到 FaaS 函數。問題在於 API 閘道提供機會在它們自己的組態/定義網域中執行許多特定應用程式邏輯。此邏輯通常難以測試、版本控制,有時甚至難以定義。通常,此類邏輯最好保留在程式碼中,就像應用程式的其他部分一樣。

不過,這裡肯定存在緊張關係。如果我們將 API 閘道視為 BaaS,那麼考慮它提供給我們的所有選項以節省我們的工作,這不是很有價值嗎?而且,如果我們是按要求而非按 CPU 使用率支付 API 閘道的使用費,那麼最大化 API 閘道功能的使用豈不是更具成本效益嗎?

我的指導原則是明智地使用增強的 API 閘道功能,而且僅在它真的能從長遠來看為你省力時才使用,包括在部署、監控和測試的方式中。絕對不要使用無法在可來源控制的組態檔或部署指令碼中表達的 API 閘道功能。

關於定義的難度,Amazon 的 API 閘道過去會強迫你建立一些棘手的組態,以將 HTTP 要求和回應對應到 Lambda 函數或從 Lambda 函數對應出來。大部分內容已透過 Lambda 代理整合 變得更為簡單,但你仍然需要了解一些偶爾會遇到的棘手細微差別。這些元素本身使用開源專案變得更容易,例如 Serverless FrameworkClaudia.js,或 Amazon 的 無伺服器應用程式模型

操作延後

我先前提到 Serverless 並非「無作業」—從監控、架構擴充、安全性及網路觀點來看,仍然有許多工作要做。然而,在你開始時很容易忽略作業(「媽咪,不用作業系統!」)。這裡的危險在於陷入虛假的安全感。也許你的應用程式已上線並執行,但它意外出現在 Hacker News 上,你突然必須處理 10 倍的流量,而且糟糕!你意外遭受阻斷服務攻擊,卻不知道如何處理。

此處的解決方案是教育。使用無伺服器系統的團隊需要及早考慮運作活動,而供應商和社群必須提供教學,以協助他們了解這代表什麼意思。預先負載測試和混沌工程等領域,也有助於團隊自我學習。

無伺服器的未來

我們即將結束這趟進入無伺服器架構世界的旅程。在結束之前,我將討論幾個我認為無伺服器世界在未來幾個月和幾年內可能發展的方向。

減輕缺點

無伺服器仍是一個相當新的世界。因此,前一節關於缺點的說明很廣泛,而且我甚至沒有涵蓋所有可以涵蓋的內容。無伺服器的最重要發展將在於減輕固有的缺點,並移除或至少改善實作缺點。

工具

工具仍然是無伺服器的一項問題,這是因為許多技術和技巧都是新的。在過去兩年中,部署/應用程式組合和組態都有所改善,其中無伺服器架構和 Amazon 的無伺服器應用程式模型領先業界。然而,「前 10 分鐘」的體驗仍然不如預期的那麼普遍,儘管 Amazon 和 Google 可以向 Microsoft 和 Auth0 尋求更多靈感。

我一直在興奮地看到雲端供應商積極解決的一個領域是更高級的發行方法。在傳統系統中,團隊通常需要編寫自己的流程來處理「流量轉移」概念,例如藍綠部署和金絲雀發行。考量到這一點,Amazon 支援自動流量轉移,適用於 Lambda 和 API Gateway。此類概念在無伺服器系統中更有用,因為許多個別部署的元件組成一個系統,一次原子發行 100 個 Lambda 函式根本不可能。事實上,Nat Pryce向我描述了「混音器」方法的概念,我們可以在其中逐步將元件群組帶入和帶出流量。

分散式監控可能是需要大幅改善的領域。我們已經看到 Amazon 的X-Ray和各種第三方產品在這裡的早期工作,但這絕對不是一個已解決的問題。

遠端除錯也是我希望看到更廣泛應用的功能。Microsoft Azure Functions 支援此功能,但 Lambda 沒有。能夠中斷點遠端執行的函式是一項非常強大的功能。

最後,我預期會看到「元操作」工具的改進,例如如何更有效率地照料數百或數千個 FaaS 函式、設定服務等。例如,組織需要能夠在特定服務執行個體不再使用時得知(至少出於安全考量),他們需要更好的跨服務成本群組和可視性(尤其是對負擔成本責任的自主團隊),以及更多功能。

狀態管理

FaaS 缺乏持續的伺服器內狀態對許多應用程式來說沒問題,但對許多其他應用程式來說卻是致命的,無論是大型快取組或快速存取階段狀態。

對於高流量應用程式,一個可能的解決方法可能是供應商讓函式執行個體在事件之間保持運作更長時間,並讓常規的處理中快取方法發揮作用。這無法 100% 奏效,因為快取無法在每個事件中都保持熱度,但這與使用自動縮放的傳統部署應用程式已存在的疑慮相同。

更好的解決方案可能是非常低延遲的非處理中資料存取,例如能夠以非常低的網路負擔查詢 Redis 資料庫。這似乎並非難事,因為 Amazon 已在他們的 Elasticache 產品中提供主機式 Redis 解決方案,而且他們已允許使用 配置群組 相對並置 EC2(伺服器)執行個體。

不過,我認為我們更有可能看到不同類型的混合(無伺服器和有伺服器)應用程式架構被採用,以考量外部化狀態限制。例如,對於低延遲應用程式,您可能會看到一種方法,即常規的長期執行伺服器處理初始要求,從其本機和外部狀態收集處理該要求所需的所有內容,然後將完全內容化要求傳遞給無需外部查詢資料的 FaaS 函式農場。

平台改善

無伺服器 FaaS 目前的一些缺點歸因於平台的實作方式。執行時間、啟動延遲和跨函式限制是三個顯而易見的缺點。這些問題可能會由新的解決方案解決,或以可能產生額外成本的解決方法解決。例如,我想啟動延遲可以透過允許客戶要求兩個 FaaS 函式執行個體始終以低延遲提供,而客戶為這種可用性付費來減輕。Microsoft Azure Functions 在 Durable FunctionsApp Service 計畫主機函式 中包含這個想法的元素。

當然,我們會看到平台改進,而這不只是修正目前的缺點,而且也會令人興奮。

教育

許多無伺服器固有的特定供應商缺點正透過教育獲得改善。使用此類平台的每個人都需要積極思考將如此大量的生態系統主機在一個或多個應用程式供應商中的意義。我們需要思考諸如「如果一個供應商無法使用,我們是否要考慮不同供應商的平行解決方案?」以及「在部分中斷的情況下,應用程式如何優雅地降級?」等問題。

另一個教育領域是技術操作。許多團隊現在的系統管理員比以前少,而無伺服器將加速此變更。但系統管理員做的不只是設定 Unix 方塊和 Chef 腳本,他們通常是支援、網路、安全性等方面的第一線人員。

真正的 DevOps 文化 在無伺服器世界中變得更加重要,因為那些其他非系統管理員活動仍然需要完成,而且通常是開發人員現在負責這些活動。這些活動對許多開發人員和技術主管來說可能不是自然而然的,因此教育和與運營人員密切合作至關重要。

供應商提高透明度和提供更明確的預期

最後,在緩解的主題上:供應商必須更清楚地說明我們對其平台的期望,因為我們依賴它們來獲得更多我們的託管能力。雖然遷移平台很困難,但並非不可能,而且不可信賴的供應商會看到他們的客戶將業務轉移到其他地方。

模式的出現

我們對如何以及何時使用無伺服器架構的理解仍處於起步階段。現在,團隊正在向無伺服器平台提出各種想法,並看看哪些想法會成功。感謝先驅們!我們開始看到推薦實務模式的出現,而且這種知識只會增長。

我們看到的一些模式在應用程式架構中。例如,FaaS 函式在變得難以控制之前可以變多大?假設我們可以原子化部署一組 FaaS 函式,那麼建立此類分組的好方法是什麼?它們是否與我們目前將邏輯分組到微服務中的方式密切相關,或者架構的差異會將我們推向不同的方向?

無伺服器應用程式架構中一個特別有趣的活躍討論領域是它如何與事件思考互動。AWS Lambda 產品主管 Ajay Nair 在 2017 年 發表了一場精彩的演講,這是 CNCF 無伺服器工作小組討論的主要領域之一

進一步延伸,在 FaaS 和傳統「始終開啟」的持續伺服器元件之間建立混合架構的好方法是什麼?將 BaaS 引入現有生態系統的好方法是什麼?反之,一個完全或大部分 BaaS 系統需要開始採用或使用更多自訂伺服器端程式碼的警告訊號是什麼?

我們也看到更多使用模式的討論。FaaS 的標準範例之一是媒體轉換,例如,每當將大型媒體檔案儲存在 S3 儲存區時,就會自動執行一個程序在另一個儲存區中建立較小的版本。然而,我們現在也看到無伺服器在資料處理管道、高度可擴充的網路 API 中以及作為運作中的通用「黏著」程式碼中得到大量使用。其中一些模式可以作為通用元件實作,直接部署到組織中;我寫過關於 Amazon 的無伺服器應用程式儲存庫,它有這個想法的早期形式。

最後,隨著工具的進步,我們開始看到建議的操作模式。我們如何邏輯地彙總 FaaS、BaaS 和傳統伺服器的混合架構的記錄?我們如何最有效地偵錯 FaaS 函數?這些問題的許多答案和新興模式都來自雲端供應商本身,我預計這方面的活動將會增加。

全球分散式架構

在我稍早給出的寵物商店範例中,我們看到單一的寵物商店伺服器被分解成幾個伺服器端元件,以及一些邏輯移到客戶端,但基本上這仍然是一個專注於客戶端或已知位置的遠端服務的架構。

現在我們開始在無伺服器世界中看到責任分配更加模糊。一個範例是 Amazon 的 Lambda@Edge 產品:一種在 Amazon 的 CloudFront 內容傳遞網路中執行 Lambda 函數的方式。有了 Lambda@Edge,Lambda 函數現在已在全球分佈,工程師的單一上傳活動表示該函數將部署到全球 超過 100 個資料中心。這不是我們習慣的設計,並附帶了一系列限制和功能。

此外,Lambda 函數可以在 裝置上執行,機器學習模型可以在行動客戶端上執行,在您知道之前,「客戶端」和「伺服器端」的分歧似乎不再有意義。事實上,我們現在看到元件的區域性光譜,從人類使用者向外擴散。無伺服器將變得無區域。

超越「FaaS 化」

到目前為止,我所見過的大多數 FaaS 用法主要都是關於採用現有程式碼和設計概念並「FaaS 化」它們:將它們轉換成一組無狀態函數。這很強大,但我預計我們將開始看到更多抽象,甚至語言,使用 FaaS 作為基礎實作,讓開發人員在不實際將其應用程式視為一組離散函數的情況下,也能獲得 FaaS 的好處。

舉例來說,我不知道 Google 是否對其 Dataflow 產品使用 FaaS 實作,但我可以想像有人建立一個產品或開源專案來做類似的事情,並使用 FaaS 作為實作。這裡的比較類似於 Apache Spark。Spark 是用於大規模資料處理的工具,並提供非常高層級的抽象,可以使用 Amazon EMR 和 Hadoop 作為其基礎平台。

測試

我認為在無伺服器系統的整合和驗收測試方面還有很多工作要做,但其中許多工作與以更傳統方式開發的「雲原生」微服務系統相同。

這裡有一個激進的想法,就是採用諸如 生產測試監控驅動開發 等想法;一旦程式碼通過基本單元測試驗證,就部署到流量子集,並查看它與先前版本相比如何。這可以與我前面提到的流量轉移工具結合使用。這並不適用於所有情境,但它對於許多團隊來說可能是一個令人驚訝的有效工具。

可攜式實作

有幾種方法讓團隊可以使用無伺服器,同時減少對特定雲端供應商的依賴。

供應商實作的抽象化

無伺服器架構 主要存在於簡化無伺服器應用程式的運作任務,但也提供了一定程度的中立性,說明在何處以及如何部署此類應用程式。例如,能夠輕鬆地在 AWS API Gateway + Lambda 和 Auth0 網路工作任務之間切換,這將會很棒,具體取決於每個平台的運作能力。

這方面的一個棘手問題是在沒有標準化概念的情況下建模抽象的 FaaS 編碼介面,但這正是 CNCF 無伺服器工作組在 CloudEvents 上的工作。

不過,一旦運作的複雜性抬頭,提供多個平台的部署抽象有多少價值,這是一個值得懷疑的問題。例如,為一個雲端取得正確的安全性,在另一個雲端總是可能不同。

可部署的實作

建議我們在不使用第三方供應商的情況下使用無伺服器技術聽起來可能很奇怪,但請考慮以下想法

  • 也許我們是一個大型技術組織,我們希望開始為我們所有的行動應用程式開發團隊提供類似 Firebase 的資料庫體驗,但我們希望使用現有的資料庫架構作為後端。
  • 我之前談到過「有伺服器」FaaS 平台,能夠為我們的一些專案使用 FaaS 風格的架構,但出於合規、法律等原因提交在內部執行我們的應用程式。

在這些情況下,使用無伺服器方法仍然有很多好處,而這些好處並非來自供應商託管。這裡有一個先例,請考慮平台即服務 (PaaS)。最初流行的 PaaS 都是基於雲端的(例如 Heroku),但很快,人們就看到了在自己的系統上執行 PaaS 環境的好處,即所謂的「私有」PaaS(例如 Cloud Foundry,正如我在文章前面提到的)。

我認為,就像私有 PaaS 實作一樣,我們將看到 BaaS 和 FaaS 概念的開源和商業實作變得普及,尤其是與 Kubernetes 等容器平台整合的那些。

社群

已經有一個規模不小的無伺服器社群,在許多城市舉辦多場會議、聚會,還有各種線上社團。我預期這將持續成長,或許會像 Docker 和 Spring 等社群一樣。

結論

無伺服器,儘管名稱令人困惑,是一種架構風格,我們較少依賴執行自己的伺服器端系統作為應用程式的一部分。我們透過兩種技術做到這一點:BaaS,我們將第三方遠端應用程式服務緊密整合到我們應用程式的前端,以及 FaaS,將伺服器端程式碼從長期執行的元件移到短暫的函式執行個體。

無伺服器並非每個問題的正確方法,因此對於任何宣稱它將取代所有現有架構的人,請保持警覺。如果你現在要投入無伺服器系統,請小心,尤其是在 FaaS 領域。儘管有許多好處,例如擴充和節省部署工作,但也有許多缺點,例如除錯和監控,就潛伏在不遠處。

不過,這些好處不應過早被忽視,因為無伺服器架構有許多正面的面向,包括降低營運和開發成本、簡化營運管理,以及降低環境影響。但我認為最重要的優點是縮短建立新應用程式元件的回饋迴路。我是「精實」方法的超級粉絲,很大一部分原因是我認為盡早讓技術出現在最終使用者面前以取得早期回饋非常有價值,而無伺服器所帶來的縮短上市時間與此理念完全契合。

無伺服器服務,以及我們如何使用它們的理解,目前(2018 年 5 月)正處於「有點尷尬的青少年時期」。未來幾年這個領域將有許多進展,而無伺服器如何融入我們的架構工具包,將會是一件令人著迷的事。


致謝

感謝以下人士提供意見,協助撰寫本文:Obie Fernandez、Martin Fowler、Paul Hammant、Badri Janakiraman、Kief Morris、Nat Pryce、Ben Rady、Carlos Nunez、John Chapin、Robert Bagge、Karel Sague Alfonso、Premanand Chandrasekaran、Augusto Marietti、Roberto Sarrionandia、Donna Malayeri。

感謝 Badri Janakiraman 和 Ant Stanley 提供意見,協助撰寫關於此術語起源的側欄。

感謝我在 Intent Media 前團隊的成員,以適當的懷疑熱情處理這項新技術:John Chapin、Pete Gieser、Sebastián Rojas 和 Philippe René。

感謝 Sid Orlando 執行編輯。

最後,感謝我在無伺服器社群中的朋友和同事,特別是那些我在本文中連結到其內容的人。

重大修訂

2018 年 5 月 22 日:整篇文章進行實質更新。請按此了解此更新的詳細資訊。

2016 年 8 月 4 日:新增「未來」和「結論」

2016 年 7 月 25 日:新增起源側欄和「與容器的比較」區段

2016 年 7 月 18 日:新增「缺點」

2016 年 7 月 13 日:新增「優點」

2016 年 6 月 17 日:新增「什麼不是無伺服器」

2016 年 6 月 16 日:新增「拆解『功能即服務』」

2016 年 6 月 15 日:發布第一部分 - 幾個範例