
- Serverless 教程
- Serverless - 首頁
- Serverless - 簡介
- Serverless - 安裝
- Serverless - 部署函式
- Serverless - 區域、記憶體大小、超時時間
- Serverless - 服務
- Serverless - 定時 Lambda 函式
- Serverless - API 閘道器觸發的 Lambda 函式
- Serverless - 包含/排除
- Serverless - 外掛
- Serverless - 打包依賴項
- Serverless - 層建立
- Serverless - 使用 DynamoDB 的 REST API
- Serverless - Telegram 回聲機器人
- Serverless 有用資源
- Serverless - 快速指南
- Serverless - 有用資源
- Serverless - 討論
Serverless - 層建立
什麼是層?
層是一種隔離程式碼塊的方法。假設您想在應用程式中匯入 NumPy 庫。您信任該庫,並且幾乎沒有機會更改該庫的原始碼。因此,如果您不希望 NumPy 的原始碼弄亂您的應用程式工作區,您會怎麼做呢?簡單來說,您只需要 NumPy 放在其他地方,與您的應用程式程式碼隔離。層允許您完全做到這一點。您可以簡單地將所有依賴項(NumPy、Pandas、SciPy 等)捆綁到一個單獨的層中,然後在 serverless 中的 lambda 函式中簡單地引用該層。就是這樣!捆綁在該層中的所有庫現在都可以匯入到您的應用程式中。同時,您的應用程式工作區保持完全整潔。您只需檢視應用程式程式碼進行編輯。

照片由 Iva Rajovic 拍攝於 Unsplash,表示程式碼在層中的分離
層真正酷的一點是它們可以在函式之間共享。假設您部署了一個帶有包含 NumPy 和 Pandas 的 python-requirements 層的 lambda 函式。現在,如果另一個 lambda 函式需要 NumPy,您無需為此函式部署單獨的層。您可以簡單地使用前一個函式的層,它也可以與新函式一起正常工作。
這將節省您在部署期間的大量寶貴時間。畢竟,您只需要部署應用程式程式碼。依賴項已存在於現有層中。因此,許多開發人員將依賴項層保留在單獨的堆疊中。然後,他們在所有其他應用程式中使用此層。這樣,他們就不需要一遍又一遍地部署依賴項。畢竟,依賴項相當龐大。僅 NumPy 庫本身就大約 80 MB。每次更改應用程式程式碼(可能只有幾 KB)時都部署依賴項將非常不方便。
新增依賴項層只是一個例子。還有其他幾個用例。例如,serverless.com 上提供的示例涉及使用 FFmpeg 工具建立 GIF。在該示例中,他們將 FFmpeg 工具儲存在一個層中。總而言之,AWS Lambda 允許我們為每個函式最多新增 5 個層。唯一的條件是 5 個層和應用程式的總大小應小於 250 MB。
建立 python-requirements 層
現在讓我們看看如何使用 serverless 建立和部署包含所有依賴項的層。為此,我們需要 serverless-python-requirements 外掛。此外掛僅適用於 Serverless 1.34 及更高版本。因此,如果您使用的是 <1.34 版本,則可能需要升級您的 Serverless 版本。您可以使用以下命令安裝外掛:
sls plugin install -n serverless-python-requirements
接下來,您將此外掛新增到 serverless.yml 檔案的 plugins 部分,並在 custom 部分提及其配置:
plugins: - serverless-python-requirements custom: pythonRequirements: dockerizePip: true layer: true
在這裡,dockerizePip - true 啟用 docker 的使用,並允許您在 docker 容器中打包所有依賴項。我們在上一章討論了使用 docker 打包。layer - true 告訴 serverless python 依賴項應儲存在單獨的層中。現在,在這一點上,您可能想知道 serverless 如何理解要打包哪些依賴項?答案如外掛章節所述,在於 requirements.txt 檔案中。
定義層外掛和自定義配置後,您可以按如下方式將層新增到 serverless 中的各個函式中:
functions: hello: handler: handler.hello layers: - { Ref: PythonRequirementsLambdaLayer }
關鍵字 PythonRequirementsLambdaLayer 來自 CloudFormation 參考。通常,它源自層的名稱。語法為 'LayerNameLambdaLayer'(標題大小寫,無空格)。在我們的例子中,由於層名稱是 python 需求,因此引用變為 PythonRequirementsLambdaLayer。如果您不確定 lambda 層的名稱,可以透過以下步驟獲取:
執行 sls package
開啟 .serverless/cloudformation-template-update-stack.json
搜尋 'LambdaLayer'
在同一區域中的另一個函式中使用現有層
正如我在開頭提到的,層真正酷的一點是能夠在您的函式中使用現有層。這可以透過使用現有層的 ARN 輕鬆完成。使用 ARN 將現有層新增到函式的語法非常簡單:
functions: hello: handler: handler.hello layers: - arn:aws:lambda:region:XXXXXX:layer:LayerName:Y
就是這樣。現在,具有指定 ARN 的層將與您的函式一起工作。如果層包含 NumPy 庫,您可以繼續在您的“hello”函式中呼叫 import numpy。它將執行而不會出現任何錯誤。
如果您想知道從哪裡可以獲取 ARN,實際上非常簡單。只需導航到 AWS 控制檯中包含該層的函式,然後單擊“層”。

當然,如果層不屬於您的賬戶,則需要公開共享或專門與您的賬戶共享。稍後將詳細介紹。
此外,請記住,層應與您的應用程式相容。不要期望與 node.js 執行時相容的層能夠與在 python3.6 執行時中建立的函式一起執行。
非需求/通用層
如開頭所述,層的主要功能是隔離程式碼塊。因此,它們不需要僅包含依賴項。它們可以包含您指定的任何程式碼段。在 custom 中的 pythonRequirements 中呼叫 layer: true 是 serverless-python-requirements 外掛實現的一種快捷方式。但是,要建立通用層,serverless.yml 中的語法(如 serverless 文件 中所述)如下:
layers: hello: path: layer-dir # required, path to layer contents on disk name: ${opt:stage, self:provider.stage, 'dev'}-layerName # optional, Deployed Lambda layer name description: Description of what the lambda layer does # optional, Description to publish to AWS compatibleRuntimes: # optional, a list of runtimes this layer is compatible with - python3.8 licenseInfo: GPLv3 # optional, a string specifying license information # allowedAccounts: # optional, a list of AWS account IDs allowed to access this layer. # - '*' # note: uncommenting this will give all AWS users access to this layer unconditionally. retain: false # optional, false by default. If true, layer versions are not deleted as new ones are created
由於提供了註釋,因此各種配置引數不言而喻。除了“path”之外,所有其他屬性都是可選的。path 屬性是您希望從應用程式程式碼中隔離的任意目錄的路徑。它將被壓縮併發布為您的層。例如,在 serverless 上的示例專案 中,他們將 FFmpeg 工具託管在一個層中,他們在名為“layer”的單獨資料夾中下載該工具,並在 path 屬性中指定該資料夾。
layers: ffmpeg: path: layer
如前所述,我們可以在 layers 屬性中新增最多 5 個層。
要將這些通用層用於您的函式,您可以再次使用 CloudFormation 參考或指定 ARN。
允許其他賬戶訪問層
只需在 'allowedAccounts' 屬性中提及賬戶編號,即可為更多賬戶提供對您的層的訪問許可權。例如:
layers: testLayer: path: testLayer allowedAccounts: - 999999999999 # a specific account ID - 000123456789 # a different specific account ID
如果要使層可公開訪問,可以在 allowedAccounts 中新增 '*':
layers: testLayer: path: testLayer allowedAccounts: - '*'