針對 Ruby Lambda 函數使用層 - AWS Lambda

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

針對 Ruby Lambda 函數使用層

使用 Lambda 層來封裝您要在多個函數之間重複使用的程式碼和相依性。層通常具備程式庫相依性、自訂執行期或組態檔案。建立層包含三個一般步驟:

  1. 封裝層內容。這表示建立 .zip 封存檔,其中包含您要在函數中使用的相依項。

  2. 在 Lambda 中建立層。

  3. 將層新增至函數中。

封裝層內容

若要建立 layer,請將套件綁定到符合下列要求的 .zip 檔案封存中:

  • 使用您計劃用於 Lambda 函數的相同 Ruby 版本建立 layer。例如,如果您為 Ruby 3.4 建立 layer,請使用 Ruby 3.4 執行時間做為函數。

  • 您 layer 的 .zip 檔案必須使用下列其中一個目錄結構:

    • ruby/gems/x.x.x (其中 x.x.x 是您的 Ruby 版本,例如 3.4.0)

    • ruby/lib

    如需詳細資訊,請參閱每個 Lambda 執行時間的層路徑

  • 層中的套件必須與 Linux 相容。Lambda 函數會在 Amazon Linux 上執行。

您可以建立包含第三方 Ruby Gem 套件或您自己的 Ruby 模組和類別的層。許多熱門的 Ruby Gem 套件都包含原生延伸模組 (C 程式碼),必須針對 Lambda Linux 環境進行編譯。

純 Ruby Gem 套件僅包含 Ruby 程式碼,不需要編譯。這些 Gem 套件在不同的平台上封裝和運作更為簡單。

使用純 Ruby Gem 套件建立圖層
  1. 建立 Gemfile以指定您要包含在 layer 中的純 Ruby Gem:

    範例 Gemfile
    source 'https://rubygems.org' gem 'tzinfo'
  2. 使用 Bundler 將 Gem 安裝至 vendor/bundle 目錄:

    bundle config set --local path vendor/bundle bundle install
  3. 將已安裝的 Gem 複製到 Lambda 需要的目錄結構ruby/gems/3.4.0):

    mkdir -p ruby/gems/3.4.0 cp -r vendor/bundle/ruby/3.4.0*/* ruby/gems/3.4.0/
  4. 壓縮圖層內容:

    Linux/macOS
    zip -r layer.zip ruby/
    PowerShell
    Compress-Archive -Path .\ruby -DestinationPath .\layer.zip

    .zip 檔案的目錄結構看起來應該如下所示:

    ruby/              
    └── gems/
        └── 3.4.0/
            ├── gems/
            │   ├── concurrent-ruby-1.3.5/
            │   └── tzinfo-2.0.6/
            ├── specifications/
            ├── cache/
            ├── build_info/
            └── (other bundler directories)
    注意

    您必須在函數程式碼中個別要求每個 Gem。您無法使用 bundler/setupBundler.require。如需詳細資訊,請參閱在函數中使用來自圖層的 Gem

許多熱門的 Ruby Gem 套件都包含原生延伸模組 (C 程式碼),必須針對目標平台進行編譯。具有原生擴充功能的熱門 Gem 套件包括 nokogiripgmysql2sqlite3ffi。這些 Gem 套件必須建置在與 Lambda 執行時間相容的 Linux 環境中。

使用具有原生延伸項目的 Gem 套件建立圖層
  1. 建立 Gemfile

    範例 Gemfile
    source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
  2. 使用 Docker 在與 Lambda 相容的 Linux 環境中建置 Gem 套件。在 Dockerfile 中指定AWS 基礎映像

    範例 Ruby 3.4 的 Dockerfile
    FROM public.ecr.aws/lambda/ruby:3.4 # Copy Gemfile COPY Gemfile ./ # Install system dependencies for native extensions RUN dnf update -y && \ dnf install -y gcc gcc-c++ make # Configure bundler and install gems RUN bundle config set --local path vendor/bundle && \ bundle install # Create the layer structure RUN mkdir -p ruby/gems/3.4.0 && \ cp -r vendor/bundle/ruby/3.4.0*/* ruby/gems/3.4.0/ # Create the layer zip file RUN zip -r layer.zip ruby/
  3. 建置映像並擷取 layer:

    docker build -t ruby-layer-builder . docker run --rm -v $(pwd):/output --entrypoint cp ruby-layer-builder layer.zip /output/

    這會在正確的 Linux 環境中建置 Gem 套件,並將layer.zip檔案複製到您的本機目錄。.zip 檔案的目錄結構看起來應該如下所示:

    ruby/
    └── gems/
        └── 3.4.0/
            ├── gems/
            │   ├── bigdecimal-3.2.2/
            │   ├── csv-3.3.5/
            │   ├── httparty-0.23.1/
            │   ├── mini_mime-1.1.5/
            │   ├── multi_xml-0.7.2/
            │   ├── nokogiri-1.18.8-x86_64-linux-gnu/
            │   └── racc-1.8.1/
            ├── build_info/
            ├── cache/
            ├── specifications/
            └── (other bundler directories)
    注意

    您必須在函數程式碼中個別要求每個 Gem。您無法使用 bundler/setupBundler.require。如需詳細資訊,請參閱在函數中使用來自圖層的 Gem

使用您自己的程式碼建立 layer
  1. 為您的 layer 建立所需的目錄結構:

    mkdir -p ruby/lib
  2. ruby/lib目錄中建立 Ruby 模組。下列範例模組透過確認訂單包含必要資訊來驗證訂單。

    範例 ruby/lib/order_validator.rb
    require 'json' module OrderValidator class ValidationError < StandardError; end def self.validate_order(order_data) # Validates an order and returns formatted data required_fields = %w[product_id quantity] # Check required fields missing_fields = required_fields.reject { |field| order_data.key?(field) } unless missing_fields.empty? raise ValidationError, "Missing required fields: #{missing_fields.join(', ')}" end # Validate quantity quantity = order_data['quantity'] unless quantity.is_a?(Integer) && quantity > 0 raise ValidationError, 'Quantity must be a positive integer' end # Format and return the validated data { 'product_id' => order_data['product_id'].to_s, 'quantity' => quantity, 'shipping_priority' => order_data.fetch('priority', 'standard') } end def self.format_response(status_code, body) # Formats the API response { statusCode: status_code, body: JSON.generate(body) } end end
  3. 壓縮圖層內容:

    Linux/macOS
    zip -r layer.zip ruby/
    PowerShell
    Compress-Archive -Path .\ruby -DestinationPath .\layer.zip

    .zip 檔案的目錄結構看起來應該如下所示:

    ruby/              
    └── lib/
        └── order_validator.rb
  4. 在您的 函數中, 需要並使用 模組。您必須在函數程式碼中個別要求每個 Gem。您無法使用 bundler/setupBundler.require。如需詳細資訊,請參閱在函數中使用來自圖層的 Gem。範例:

    require 'json' require 'order_validator' def lambda_handler(event:, context:) begin # Parse the order data from the event body order_data = JSON.parse(event['body'] || '{}') # Validate and format the order validated_order = OrderValidator.validate_order(order_data) OrderValidator.format_response(200, { message: 'Order validated successfully', order: validated_order }) rescue OrderValidator::ValidationError => e OrderValidator.format_response(400, { error: e.message }) rescue => e OrderValidator.format_response(500, { error: 'Internal server error' }) end end

    您可以使用下列測試事件來叫用 函數:

    { "body": "{\"product_id\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}" }

    預期的回應:

    { "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"product_id\":\"ABC123\",\"quantity\":2,\"shipping_priority\":\"express\"}}" }

在 Lambda 中建立 layer

您可以使用 AWS CLI 或 Lambda 主控台發佈 layer。

AWS CLI

執行 publish-layer-version AWS CLI 命令來建立 Lambda layer:

aws lambda publish-layer-version --layer-name my-layer --zip-file fileb://layer.zip --compatible-runtimes ruby3.4

相容的執行時間參數是選用的。指定時,Lambda 會使用此參數來篩選 Lambda 主控台中的圖層。

Console
建立圖層 (主控台)
  1. 開啟 Lambda 主控台中的 層頁面

  2. 選擇 建立圖層

  3. 選擇上傳 .zip 檔案,然後上傳您先前建立的 .zip 封存檔。

  4. (選用) 對於相容的執行時間,選擇對應於您用於建置 layer 的 Ruby 版本的 Ruby 執行時間。

  5. 選擇建立

在函數中使用來自圖層的 Gem

在函數程式碼中,您必須明確要求要使用的每個 Gem 套件。不支援 Bundler 命令,例如 Bundler.require bundler/setup和 。以下是如何在 Lambda 函數中正確使用來自圖層的 Gem:

# Correct: Use explicit requires for each gem require 'nokogiri' require 'httparty' def lambda_handler(event:, context:) # Use the gems directly doc = Nokogiri::HTML(event['html']) response = HTTParty.get(event['url']) # ... rest of your function end # Incorrect: These Bundler commands will not work # require 'bundler/setup' # Bundler.require

將 layer 新增至函數

AWS CLI

若要將 layer 連接至函數,請執行 update-function-configuration AWS CLI 命令。對於 --layers 參數,請使用 layer ARN。ARN 必須指定版本 (例如 arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1)。如需詳細資訊,請參閱層和層的版本

aws lambda update-function-configuration --function-name my-function --cli-binary-format raw-in-base64-out --layers "arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1"

如果您使用的是第 2 AWS CLI 版,則需要 cli-binary-format選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》AWS CLI 支援的全域命令列選項

Console
將圖層新增至函數
  1. 開啟 Lambda 主控台中的函數頁面

  2. 選擇 函數。

  3. 向下捲動至區段,然後選擇新增層

  4. 選擇圖層下,選取自訂圖層,然後選擇您的圖層。

    注意

    如果您在建立 layer 時未新增相容的執行時間,您的 layer 將不會列在此處。您可以改為指定 layer ARN。

  5. 選擇新增

範例應用程式

如需如何使用 Lambda 層的更多範例,請參閱《 AWS Lambda 開發人員指南 GitHub 儲存庫》中的 layer-ruby 範例應用程式。此應用程式包含包含 tzinfo 程式庫的 layer。建立 layer 之後,您可以部署和叫用對應的 函數,以確認 layer 如預期般運作。