本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
針對 Ruby Lambda 函數使用層
使用 Lambda 層來封裝您要在多個函數之間重複使用的程式碼和相依性。層通常具備程式庫相依性、自訂執行期或組態檔案。建立層包含三個一般步驟:
-
封裝層內容。這表示建立 .zip 封存檔,其中包含您要在函數中使用的相依項。
-
在 Lambda 中建立層。
-
將層新增至函數中。
封裝層內容
若要建立 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 套件建立圖層
-
建立
Gemfile
以指定您要包含在 layer 中的純 Ruby Gem:範例 Gemfile
source 'https://rubygems.org' gem 'tzinfo'
-
使用 Bundler 將 Gem 安裝至
vendor/bundle
目錄:bundle config set --local path vendor/bundle bundle install
-
將已安裝的 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/
-
壓縮圖層內容:
.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/setup
或Bundler.require
。如需詳細資訊,請參閱在函數中使用來自圖層的 Gem。
許多熱門的 Ruby Gem 套件都包含原生延伸模組 (C 程式碼),必須針對目標平台進行編譯。具有原生擴充功能的熱門 Gem 套件包括 nokogiri
使用具有原生延伸項目的 Gem 套件建立圖層
-
建立
Gemfile
。範例 Gemfile
source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
-
使用 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/ -
建置映像並擷取 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/setup
或Bundler.require
。如需詳細資訊,請參閱在函數中使用來自圖層的 Gem。
使用您自己的程式碼建立 layer
-
為您的 layer 建立所需的目錄結構:
mkdir -p ruby/lib
-
在
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
-
壓縮圖層內容:
.zip 檔案的目錄結構看起來應該如下所示:
ruby/ └── lib/ └── order_validator.rb
-
在您的 函數中, 需要並使用 模組。您必須在函數程式碼中個別要求每個 Gem。您無法使用
bundler/setup
或Bundler.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。
在函數中使用來自圖層的 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 新增至函數
範例應用程式
如需如何使用 Lambda 層的更多範例,請參閱《 AWS Lambda 開發人員指南 GitHub 儲存庫》中的 layer-ruby