Categories
程式開發

Serverless:我還是一個大孩子


無服務器計算成熟了嗎?

每年,軟件工程行業都會冒出各種新工具和新趨勢。 由於我已經研究一段時間了,我想是時候開始開發一個像樣的雷達工具,來發現哪些趨勢將產生持久的影響,而哪些趨勢將虎頭蛇尾。 可以肯定的是,我曾做過一些令人尷尬的預測,例如和我的一個朋友打賭Git會輸給Mercurial,因為Git的用戶功效學太差了。 但我們都知道結果如何。

但總的來說,對於什麼樣的技術會成為贏家,而什麼樣的技術會成為敗者,我認為我自己有著很好的認識。 而談到無服務器計算時,我還不需要使用任何專業知識。

等等,什麼? 不需要任何專業知識?

是的,你沒看錯。 根本不需要一個預言家就可以看到,無服務器計算就是未來。 沒人想要管理服務器。 管理服務器是執行代碼的一個令人討厭的副作用。 我需要一個安全的環境來運行代碼,而根據馮諾依曼架構,我需要一些內存、一些硬盤空間和一個處理器。 我其實並不關心這些東西是什麼形式,只需要數量足夠就可以了。 我的代碼需要以上三種資源,而我需要一個環境為我提供這些資源。 就是這麼簡單。

我想要運行代碼並不意味著我想要管理一個服務器或者代碼運行的環境。 在理想情況下,我會去找一個雲服務商,然後告訴他“這是我的應用程序,幫我讓它運行吧。”

什麼是Serverless?

在開始之前,讓我們先來了解下Serverless到底是什麼。 你會看到一些Serverless的定義,說它根據需要提供計算資源。 而這只是一個純粹的定義,更常用的定義是,這是一種可以向你提供計算資源而不需要你自己關心服務器管理的方法。

Serverless有以下幾種形式

無服務器容器

無服務器容器服務,例如HerokuNetlifyAWS ECS / EKS FargateGoogle Kubernetes引擎Azure Kubernetes服務為你提供一個環境,​​你可以在其中構建一個容器並將其推送到一個管理容器部署和運行的服務中。 你不必擔心託管控制服務器、節點服務器等集群的運行,你只需要向上推一個包含一些元數據的容器,其餘的由這個服務處理。

無服務器函數

無服務器函數,例如AWS LambdaGoogle Cloud功能或者Azure功能等服務提供了一個環境,​​你能在那個環境中使用特定的接口上傳一段代碼,然後調用這段代碼。

Serverless vs 虛擬機

許多人並不認為無服務器容器是真正的Serverless,因為當你構建和推送一個容器時,你實際上是把整個服務器打到一個包中。 雖然我傾向於同意它們並不是 真實 Serverless,但它們絕對比運行完整的虛擬機有巨大的好處,而且在某些場景比無服務器函數有明顯優勢。

無服務器容器的優點

無服務器容器比傳統服務器有巨大優勢。 下面是其中一些優勢:

1。服務器管理事項很少——不用管理、修補或故障排除服務器。 容器內仍然有一個操作系統,但那可以是一個非常極簡的安裝版,而且要管理的東西會非常少。

2。通常是無狀態的——當構建針對容器的應用程序時,你通常是在構建一個12因子應用程序或者遵循類似的模式。 你的容器是牲畜,而不是寵物。 如果你的容器崩潰了,一個新的容器會自動激活。

3。容易橫向擴展——虛擬機在擴展性方面本質上沒有任何限制,但是容器將你推往一個可以允許無服務器容器服務按需擴展你的軟件的方向。 基於負載、請求時長和請求數量,你的無服務器容器服務可以運行一個或10000個容器實例,同時透明地處理存儲分配、負載均衡、路由等。

4。安全——在容器中安裝的操作系統通常是短暫的、簡小的而且有時是只讀的。 因此,它提供的攻擊面比典型的通用和長期服務器環境要小得多。

5,源碼可控的環境——你的容器定義是在一個可以放入源碼控制的文件中描述的。 雖然這是當前幾乎任何環境下的最佳實踐,但與傳統服務器環境相對還是有明顯的優勢。 在傳統服務器環境,有人可以接入服務器並篡改服務器配置。

6。應用程序和環境打包——將應用程序與其所運行的環境結合起來,並將其作為一個單獨的單元部署。 這樣的話,如果你的軟件的新版本使用了更新了的庫、操作系統版本或者語言版本,它可以作為一個單獨的單元部署和回滾。

7。成本——你可以輕鬆上下調整你的工作負載。 雖然運行一個無服務器容器可能會稍微貴一點,但你可以靈活地在幾個服務商之間做取捨。 與傳統的虛擬機選項相比,無服務器容器通常為你提供了更大的靈活性,可以將資源分割成更小的單元。 例如,一個EC2 T3實例提供2個vCPU,但是你能只用0.25個vCPU請求一個容器。

無服務器函數的優點

無服務器函數擁有無服務器容器的所有優點,但是將其提升到了另外一個級別。

1。幾乎零管理——在大部分情況下,你不需要考慮操作系統。 你只需要推送你的代碼,然後運行它們。 在操作系統級別沒有什麼需要修補,也沒有什麼需要維護——只要推送代碼,然後忘了這回事就可以了。

2。默認無狀態——無服務器函數強制你用一種無狀態的方式編寫代碼,因此你不能依賴於調用之間的任何內容。 這使得無服務器函數很容易擴展,因為你的函數可以在任何服務器上激活而不依賴本地狀態。

3。幾乎完美的水平擴展——某些東西調用了你的函數,然後它運行了。 調用一次,就運行一次。 調用10000次,就運行10000次。 當然,運行中可能會有一些平台限制,但這些通常是為了防​​止意外花費10000美元的保障措施,而不是平台的限制。

4。成本——無服務器函數只在執行時花錢。 因此,如果你只有一些不常執行的函數,或者偶爾大量執行的函數,你可以節省很多成本。

無服務器容器vs 無服務器函數

無服務器容器的優勢

1。容易遷移——如果你有一個現成的應用程序,可能需要一點兒工作,但是你可以讓它在容器中運行。

2。對於穩定的工作負載來說更便宜——如果你的工作負載穩定,那麼無服務器容器會比同等調用量的無服務器函數更便宜。

3。靈活性——對於操作系統、二進製文件、語言、版本等沒有限制。 你完全控制整個容器。 無服務器函數服務會限制你使用特定的運行時和版本。 一些無服務器函數服務允許自定義運行時,但你還是會被鎖定在操作系統中。

4。故障排除——容器使得你可以輕鬆介入並診斷你的線上環境正在發生的故障情況。 它們還允許你在本地環境運行部分系統,這使得調試發生了什麼更容易。

5,長期運行的任務——無服務器容器一直運行,這最適合長期運行的任務。 大部分無服務器函數對於一個函數會執行多上時間都會有限制。 例如,在本文撰寫的當下,AWS Lambda有一個15分鐘的限制。

無服務器函數的優勢

1。對於突增的工作負載的成本更低——無服務器函數是根據調用量付費的,這意味著你只需要在代碼實際運行時付費。 這意味著,對於那些不經常運行的工作負載,它們會比傳統服務器或容器更便宜。

2。快速擴展——無服務器函數服務可以在幾秒(有時甚至不到一秒)內創建一個你的函數實例並讓它響應流量請求。 對此會有一些特定的限制,你可以在下面的“擴展無服務器函數”章節看到關於這些限制的更多討論。

3。細粒度的可擴展性——假設你有一個應用程序,它由許多不同的無服務器函數組成,而其中一個函數的調用次數比其他函數的調用次數多了1000倍。 那麼這個調用次數特別大的函數將獨立於其它函數進行擴展,你甚至不需要考慮它。

無服務器容器的劣勢

1。部署方式比較重——無服務器容器通常需要一個大型的構建步驟,然後你需要將一個幾百兆字節的容器推到你的倉庫。 然後你需要在你的集群中部署你的容器,而如果你的部署很大的話可能會需要一點兒時間。

2。粗粒度擴展——當你部署一個無服務器函數時,你只是部署了一個單獨的函數。 那個函數可能會執行多個任務,但是通常你都會部署一個單一目的的函數,這個函數可以獨立於其它函數擴展。 當你部署一個無服務器容器時,你通常會部署整個應用程序或微服務。 那個應用程序或微服務的所有功能都會被部署到一個單獨的容器,因此想要擴展它的話就要準備那個容器的更多實例。 這意味著整個事情作為一個單獨的單元擴展。 如果你的應用程序的一部分被大量點擊,那麼你需要擴展整個應用程序來增加可以響應的流量。

無服務器函數的劣勢

1。缺乏控制——某個人在管理運行代碼的服務器。 你的代碼運行在一個操作系統中,而你對此沒有任何控制。

2。專有性——圍繞無服務器函數沒有任何真正的標準。 因此,你通常是使用特定供應商的工具和接口來編寫你的無服務器應用程序。 使用諸如AWS step函數之類的工具會與供應商強關聯,因為目前跨無服務器函數的編排還沒有一點兒標準。 這會使得你深度陷入特定供應商的生態系統,而讓切換供應商變得比較困難。

3。重寫——拿到一個現有的應用程序,讓它用無服務器函數來工作通常來說是不可能的。 你基本上通常不得不從零開始編寫你的應用程序來利用無服務器函數的優勢。

4。可追溯性——無服務器函數擁有和微服務一樣的挑戰,但更極端。 跟踪貫穿你係統的單個請求會涉及很多無服務器函數。 你需要確保你使用了諸如AWS X射線Google Cloud Trace或者Azure中的分佈式跟踪之類的工具。

5,調試/測試——你可以使用無服務器Google功能框架或者AWS SAM等工具在本地機器上輕鬆運行一個雲函數,但得到實際的調用會比較困難,因為雲函數通常和雲生態系統以自動化的專有的方式集成在一起。 另外,諸如AWS step函數之類的服務在不同lambda之間引入了編排層,會使得調試線上環境正在發生什麼更加困難。

6。部署——無服務器函數的部署會是一個挑戰,但大部分是因為他們提供的工具(例如一個集成開發環境)鼓勵不良行為。 使用無服務器框架會使得你的部署更自動化和可管理,但是你需要努力去設置並管理它,不然版本控制和維護成百上千個函數將會非常痛苦。

擴展無服務器函數

擴展無服務器函數需要一點兒額外的注意,因為人們通常認為像AWS Lambda或GCP雲函數之類的工具是針對擴展能力的萬能之計。 它們假定你只需要推送你的雲函數,幾乎馬上就會獲得可擴展性。 但這與事實相差太遠。 這些無服務器函數服務使得擴展變得異常簡單,但是平台的局限性會影響函數擴展的速度和高度。

例如,AWS Lambda有個初始的每個區域1000函數並發調用量的限制(這是指這個區域的所有函數)。 這個限制是作為一個安全措施來防止意外的資源使用,而且可以通過聯繫AWS客戶支持來增加。

基於此,你可能認為你能夠呼叫AWS客戶支持並請求將並發調用量增加到20000,然後你就可以推大量請求到你的Lambda函數並使它快速擴展到對應的級別來應對你的服務需求。 不幸的是,事實並非如此。

即使你讓AWS客戶支持將你的限制增加到20000並發調用量,AWS Lambda仍然會限制你每分鐘只能增加500並發調用量,這意味著如果你是從0開始的話需要40分鐘才能增加到20000並發調用量。 同時,所有訪問你的服務但不能被路由到激活的函數的請求都會收到429錯誤。

如果你知道你的流量會比當前突增,你可以購買Amazon的“預配置並發”功能。 該功能將保持特定數目的Lambda函數待命,但是你將放棄無服務器函數的一些優勢,因為你需要支付來保持這些函數一直運行。 但是,在某些場景中,這種權衡是值得的。

還有一個擔憂是,單獨某個函數會佔用特定區域的所有可用的並發量。 你可以為特定的函數配置“保留並發”,來保證它們的並發量不會被其它函數完全消耗。 但是假如你總共有5000並發量並將某個函數的保留並發量設為1000,那麼你在那個區域的所有其它函數就只剩下4000並發量。

雖然這些設置中的許多設置都是提供一個安全又可用的環境所必需的,但它能夠為剛開始使用無服務器函數的新手帶來許多驚喜。

供應商鎖定

幾乎所有的雲平台都會抓住每一個機會來讓你鎖定,Serverless也不例外。 然而與無服務器容器相比,無服務器函數更關心供應商鎖定問題。 調用、部署、編排和分配函數的方式都取決於你所使用的雲供應商。

基尼特語這樣的項目正在努力創建一個企業可以用來部署無服務器工作負載的標準環境,但是,一般來說,你必須部署和管理平臺本身才能獲得好處。 這會抵消用無服務器方式運行代碼的許多優點。 目標是避免運行基礎設施,對嗎? 我要提到的是,你可以通過Google Cloud Run獲得對Knative的本地支持,並且通過一些努力,可以在AWS Fargate上運行Knative。

對無服務器函數有什麼反對意見?

可能聽起來我們不喜歡無服務器函數,但事實並非如此。 我們只是認為它們的用途比無服務器容器更有限。 在某些特定場景下,無服務器函數是完美的解決方案。 令人驚訝的是,通常你需要與底層雲平台強集成。 假設你想要上傳一張圖片到S3,並讓它自動觸發一個雲函數以某種方式處理這張圖片;或者你有一些Cloudwatch這樣的日誌服務生產的日誌,並且想要有一段代碼來輕鬆地分析日誌流。 這時,無服務器函數才真正展現出它們的價值。 當你有一些需要擴展的應用程序的熱點端點,而你想要用與其它端點不同的擴展方式擴展它們時,無服務器函數也非常適合。

正如所知,在大多數情況下,我們仍然推薦無服務器容器。 但是你不會看到我們為此欣喜若狂,因為無服務器容器並不能提供無服務器計算的聖杯。 無服務器計算的聖杯是什麼? 我很高興你問到這一點。

無服務器計算的聖杯

無服務器計算的聖杯是效用計算。 當我需要的時候,讓我所有的資源都按我需要的樣子可用。 能夠上傳一段代碼(無論是單個函數還是整個應用程序)以及一點兒元數據,並允許其無限擴展(附帶一些安全限制)。 為了不必考慮它需要多少內存、存儲或計算資源,它只需要自動計算出來。 無服務器函數實際上比無服務器容器更接近於此,但是由於上面提到的原因,它們仍然沒有達到目標。

Serverless都長大了

請不要把這篇文章解釋為我不認為無服務器函數或容器已經準備好在現實世界採用。 對於大多數組織來說,運行服務器應該和產生他們自己的能力一樣重要(一些大型組織需要同時做到這兩個!)。 使用無服務器計算,你的代碼仍然運行在某個地方的一台服務器上,只是你不需要再關心這台服務器。 對於大部分組織來說,這確實是一個長期的目標,使得能夠將一段代碼推送到某個服務中並讓它運行。 無服務器計算並不能實現“上傳代碼,然後忘掉它”的夢想,但是我們已經接近了。

無服務器計算在這裡,並將繼續存在。 我們將看到無服務器服務越來越接近這裡描述的理想化的情景。 但是,雖然Serverless已經成熟了,但我們還有一段路要走。 為了真正實現無服務器計算的理想,我們需要審慎地重新思考當前的計算和安全模型。 雖然挑戰是巨大的,但回報更大,因此我們可能比我們想像的更快實現這個理想。

作者簡介

賈斯汀·埃瑟里奇(Justin Etheredge)一位專注於雲計算、Serverless的博主。

原文鏈接無服務器:我現在是個大孩子