天天看點

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

先看下 CNCF 2020 (2021年的還沒出)

Serverless

調查報告顯示的資料,雲計算廠商中的

Serverless

産品使用率中

AWS Lambda

占 57% ;開源

Serverless

平台平台使用率中

Knative

占 27% 。

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章
典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

本文主要介紹

Lambda

上的

Serverless

典型架構

那麼

AWS Lambda

吸引人的地方在于:自動擴縮容及按使用量計費。當然還有一個主要原因,AWS 提供的其他服務也是相當豐富(

API gateway

,鑒權,資料庫,工作流等等)。給中小型企業充分發揮的餘地,充分利用

AWS

提供的這些能力組建自己的

Serverless

形态産品架構。

本文以

Theodo

公司的一個

Web

項目為例,介紹典型的 Serverless 架構是怎樣的,首先看下項目的全景圖,看不懂沒關系,接下來分解開來講解。

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

關注公衆号,回複“serverless架構圖”檢視高清圖檔

在上述圖表中, 方框代表的是存在于大多數

Serverless

架構中的典型技術領域或技術功能。

一、Serverless 實踐思路

此項目的目标是擁有一個強大的完全托管的系統,并提供友好的開發人員體驗。為了實作這一目标,

Theodo

公司采取了以下措施:

1. 選擇 AWS

雲技術的競争很激烈:亞馬遜雲服務(

AWS

)、谷歌雲服務(

GCP

)、微軟雲服務(

Azure

)、

IBM

雲服務、阿裡雲服務。這些平台都提供了自己的雲計算産品,并且特性都在快速疊代中。

Ben Ellerby

在這篇文章[1]中比較了前三名的雲服務提供商,而我們更青睐于

AWS

的解決方案。在

Serverless

架構方面,

AWS

是最先進的。借助

AWS

的解決方案,我們可以盡可能接近

Serverless

架構。為了說明這一點,我們将在下文中詳細介紹構成我們架構子產品的每個

AWS

服務。

2. 使用 TypeScript 開發 Node.js 項目

JavaScript

是世界上最受歡迎的程式設計語言之一,社群也很活躍,根據

Datadog

的調查(可參考之前發的一篇公衆号文章),

Serverless

架構中也是如此。盡管

Python

以 47%的占有率領先,但目前已部署的

Lambdas

中有 39% 是運作

JavaScript

的。

TypeScript

豐富了

JavaScript

的特性。最後說明下, 在絕大多數用例中,

Lambdas

中的

JavaScript

都運作得很好。

3. Serverless Framework

Serverless Framework

完成了大部分基礎架構即代碼(

Infrastructure as Code, IaC

)的工作(基于

CloudFormation

CloudFormation

AWS

提供的一個基礎設定編排工具)。定義一個對

HTTP

事件做出響應的

Lambda

函數,

Serverless

架構架構将自動部署相關的

API Gateway

資源、相應的路由以及新的

Lambda

函數。當需要更複雜的服務配置時,隻需簡單地添加一些

CloudFormation

即可 。

4. 細粒度的 Lambda 函數

Lambda

是一個函數,它有自己的工作任務,并且能做得很好。比如:

  • 項目的前端需要獲得一個項目清單,那這個功能可以建立一個

    Lambda

    函數。
  • 當使用者注冊後,我們需要發送确認電子郵件, 為這個功能也可以建立一個

    Lambda

    函數。
  • 當然,某些特定的代碼(例如資料實體

    Entity

    )可以分解成小的單元,并在專用的

    utilities

    檔案夾中共享。但一定要非常小心這些代碼,因為任何更改都會影響所有相關的

    Lambda

    函數。而且因為每個

    Lambda

    是可以獨立測試和部署的,是以可能會遺漏一些内容(這時

    TypeScript

    就派上用場了)。

5. 分解成微服務

為了避免團隊之間互相影響,同時避免

package.json

serverless.yaml

配置檔案過大(

CloudFormation

的資源限制數量為 200)以及過長的

CloudFormation

部署時間,同時也為了友善我們在代碼庫中定位,并在所有

Lambdas

函數之間明确清晰的團隊職責:我們定義了微服務劃分的邊界。

Ben Ellerby

在這篇文章中寫了一個方法,

EventBridge Storming[2]

,來幫助定義這些界限。

在我們的單體代碼庫中:一個微服務=一個

CloudFormation

堆棧=一個

serverless.yml + package.json

。此外,微服務有隻屬于自己的資料實體,這些資料實體不會與其他微服務共享。

早期在項目中我們推薦隻使用

JavaScript

,但出于種種原因,可能想要使用另一種語言,或者可能希望逐漸遷移到

JavaScript

中的

Serverless

架構。在

Serverless

架構中,微服務的優勢是你可以在架構中混合多種技術棧,隻要保證微服務之間的抽象接口一緻即可。

6. 使用事件驅動

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

同時微服務之間需要完全獨立,如果其中一個微服務出現事故,或者正在對另一個微服務進行重大改動,這對于系統其他部分的影響應該越小越好。為實作這個目标,

Lambdas

函數僅通過

EventBridge

這個

Serverless

架構的事件總線來和其他

Lambdas

函數互動。在

這篇文章[3]

中,

Ben Ellerby

詳細叙述了為什麼

EventBridge

用途這麼大 。

二、詳解 Serverless 架構子產品

上面已經介紹了一些背景知識,接下來詳細介紹下本文開篇的

Serverless

架構圖中的每個子產品。

1. 前端開發

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

我們優秀的無伺服器後端需要以某種方式為前端提供資料。為簡化與 AWS 耦合的前端開發,我們利用了

Amplify

AWS

提供的前端架構)。

Amplify

囊括了幾個不同的東西:一個指令行工具、一個基礎架構即代碼(

IaC

)工具、一個

SDK

和一套

UI

元件。我們利用前端的 JS 的

SDK

來加快與其他資源(比如用于認證的

Cognito

)的內建,這些資源通常是通過其他 基礎架構即代碼工具(比如

Serverless Framework

)來部署的。

2. 網站托管

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

如今,大多數網站是單頁應用(

Single Page Application,SPA

),它們是功能齊全的動态應用程式,被打包在一組靜态檔案中。這些檔案是在使用者的浏覽器首次通路

URL

時下載下傳的。在

AWS

環境中,我們在

S3

AWS

的 檔案存儲服務)中托管這些靜态檔案,并通過

CloudFront

AWS

CDN

服務)來公開。

雖說上面場景是多數,但前端的趨勢仍然在朝着諸如

Next.js

之類的服務端渲染(

Server Side Rendering

,即

SSR

)發展。要在

Serverless

架構中運作一個

SSR

網站,我們可以利用

CloudFront

中的

Lambda @ Edge

。可以使用更接近使用者端的

Lambdas

函數來進行服務端渲染。

3. 域名與證書

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

在我們網站中,我們希望使用相比于原始自動生成的

S3

URL

更好的

URL

,為了做到這一點,我們使用

Certificate Manager

(

AWS

證書管理服務)來生成證書,并将其綁定在

CloudFront

AWS

CDN

服務),并使用

Route 53

AWS

的域名管理服務)來管理域名。

4. 業務邏輯接口

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

現在,我們的網站需要連接配接後端,以獲得和推送資料。為此,我們使用

API Gateway

來處理

HTTP

連接配接和路由,并為每個路由同步觸發一個

Lambda

函數。我們的

Lambda

函數包含與

DynamoDB

AWS

的非關系資料庫) 通信的業務邏輯,以便存儲和使用資料。

架構如上文所示是事件驅動的,這意味着可以立即回複使用者請求,同時繼續在背景異步地處理請求。例如,

DynamoDB

AWS

的非關系資料庫)提供了流(

Streams

),它可以對任何資料改動作出反應,并且異步地觸發

Lambda

函數。大多數

Serverless

架構的服務都有類似的功能。

5. 異步任務

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

我們項目的架構是事件驅動的,是以許多的

Lambda

函數都是異步的,通常是由

EventBridge

事件、

S3

事件、

DynamoDB

流等事件觸發。例如,我們系統中有一個異步

Lambda

函數,負責在成功注冊後發送歡迎電子郵件。

在分布式異步系統中,故障處理是非常重要的。是以對于異步的

Lambda

函數,我們使用它們的死信隊列(

Dead Letter Queue,DLQ

),并且将最終的故障資訊首先傳遞給

Simple Notification Service(SNS)

AWS

的 消息推送服務,如電子郵件,短信等),然後再傳給

Simple Queue Service(SQS)

AWS

的消息隊列服務)。我們現在必須這樣做,因為

AWS

暫時還不支援将

SQS

直接連接配接到

Lambda DLQ

上。

6. 後端向前端的推送

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

有了異步的操作,前端不能在等待一個

XHR

xhr

XMLHttpRequest

)響應時僅僅顯示一個加載頁面。我們需要後端的預備狀态和資料推送。為此,我們利用了

API Gateway

WebSocket

,這個

API

可以使

WebSocket

保持連接配接狀态,并且僅在在收到消息時觸發

Lambdas

函數。

這篇文章[4]

深入讨論了相比較于其他解決方案,為什麼我們選擇了

WebSocket

,以及如何實作它。

7. 檔案上傳

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

處理

Lambda

的檔案上傳流(

Stream

)可能會造成較大的開銷。相較于這個方案,

S3

(

AWS

的檔案存儲服務) 還提供了一個功能,使得前端能使用由

Lambda

生成的、簽名(安全)的上傳

URL

來直接上傳檔案到

S3

AWS

的檔案存儲服務)。

8. 使用者與認證

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

Cogito

(

AWS

的認證服務)有我們所需要的所有東西:認證、使用者管理、通路控制以及外部身份提供商內建。盡管大家知道它使用起來有些複雜,但它确實可以為我們做不少事情。和其他服務一樣,它由專用的

SDK

來與

Lambda

互動,并且可以通過分發事件來觸發

Lambda

。本例中,

API Gateway

路由綁定了原生

Cogito

授權服務。同時也暴露了一個用于重新整理身份驗證令牌的

Lambda

函數和一個用于擷取使用者清單的

Lambda

函數。

9. 狀态機

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

在某些情形下,我們的邏輯和資料流可能會非常複雜。如果直接在

Lambda

函數内部手動維護和操作這些資料流,正在運作的系統可能會難以跟蹤和掌控。是以,

AWS

為我們提供了專門提供了一個服務:可視化工作流服務 (

Step Functions

)。

我們通過

CloudFormation

AWS

的基礎設施編排工具)來聲明狀态機:包括每個子步驟和狀态、每個希望得到的結果和不希望得到的結果,并且将一些操作(例如等待、選擇)或者一個

Lambda

函數挂載在這些步驟上。然後,就餓可以通過

AWS

界面實時看到這些服務的運作狀态。在其中的每個步驟中,還可以定義重試和失敗處理邏輯。

Ben Ellerby

這篇文章[5]

中進一步詳細介紹了該服務。

這裡舉一個更加具體的例子,假設我們希望通過

SaaS

發送一個電子郵件廣告,并且能夠確定該廣告已經發送完畢:

  • 步驟 1,

    Lambda

    :要求

    SaaS

    發送電子郵件廣告系列并擷取廣告的

    ID

  • 步驟 2,任務令牌

    Lambda

    :從

    Step Function

    (可視化工作流服務 ) 中獲得回調令牌,将其連結到廣告

    ID

    ,然後等待來自

    SaaS

    的回調。
  • 步驟 3,(在任務流之外的)

    Lambda

    :在廣告的狀态發生改變時(待定、存檔、失敗、成功),從

    SaaS

    通過一個鈎子函數調用,然後通過對應的回調令牌根據新的廣告狀态來繼續任務流。
  • 步驟 4,選擇(

    Choice

    ):基于狀态選擇,如果這個廣告還沒有成功,回到第二步。
  • 步驟 5,(結束)

    Lambda

    :在廣告發送後,更新使用者。

這篇文章[6]

深入講述了任務令牌(

Task Tokens

)是如何工作的。

10. 安全

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

Identity and Access Management (IAM)

(

AWS

權限控制服務)可以更加細粒度地管控任何

AWS

通路,不管是開發人員的通路、持續內建與持續傳遞流程 , 還是

AWS

的服務調用另一個服務。

IAM

的管控是非常精細的,需要平台開發者認真考慮某個特定的“消費者”被允許操作的所有行為。這意味着我們基礎架構中的每一層都是受到保護的。

對于非常敏感的資料,比如

SaaS

API

密鑰,我們将其安全地存儲在

System Manager

AWS

的系統管理服務)中的

Parameter Store

中。無論是來自我們

Serverless Framework

還是

CloudFormation

檔案,甚至是來自業務代碼的通路,都必須通過對應的 SDK 來請求它們。值得一提的是,

AWS Secrets Manager

AWS

的密鑰管理軟體)也可以完成類似的工作。

如果對該話題感興趣,推薦來自

Sat G

這篇文章[6]

,關于

Serverless

中的安全問題在這篇文章中有更詳細的講解。

11. 監控

典型的 Serverless 架構是怎樣的一、Serverless 實踐思路二、詳解 Serverless 架構子產品參考文章

CloudWatch

AWS

的雲監控服務)是監控服務的業界标準。所有 AWS 服務的基礎名額和日志都可以發送到

CloudWatch

。當然我們可以做更多的事情:将自定義的名額和日志發送到

CloudWatch

,建立名額

DashBoard

,在超過門檻值後觸發警報;資料分析與挖掘整理後展現在自定義的圖表中。

可觀測性方面還有其他選擇,比如

X-Ray

AWS

分布式追蹤服務),它的目标是在整個分布式系統中端到端地追蹤請求,然後直覺動态得展現出來。隻不過現在這個追蹤服務時不時會失敗,因為它還不支援某些

AWS

服務,比如

EventBridge

(而這在我們的架構中是重中之重)。

另一個服務,基于

X-Ray

CloudWatch

建構的

ServiceLens

AWS

的可視化監控服務),效果也很贊。

原文:https://reurl.cc/R0vVKz

翻譯:zhaojizhuang

參考文章

  1. https://medium.com/serverless-transformation/choosing-the-right-cloud-provider-a-serverless-cloud-atlas-eeae672076ce

  2. https://aws.amazon.com/cn/eventbridge/

  3. https://medium.com/serverless-transformation/eventbridge-the-key-component-in-serverless-architectures-e7d4e60fca2d

  4. https://medium.com/serverless-transformation/asynchronous-client-interaction-in-aws-serverless-polling-websocket-server-sent-events-or-acf10167cc67

  5. https://medium.com/serverless-transformation/serverless-event-scheduling-using-aws-step-functions-b4f24997c8e2

  6. https://medium.com/@zaccharles/9df97fe8973c

關注公衆号:Knative,了解更多 Serverless 、Knative,雲原生相關資訊

關注公衆号,回複 “進群”,即可進群與衆多雲原生 Serverless 技術大佬探讨技術,探讨人生。

繼續閱讀