概述

AWS Lambda 是一项无服务器计算服务,允许您在不预置或管理服务器的情况下运行代码。本文将详细介绍如何使用AWS CLI管理Lambda函数,包括创建、部署、更新、监控和下载函数代码等核心操作。

基础Lambda操作

1. 创建Lambda函数

# 创建基本的Lambda函数
aws lambda create-function \
    --function-name my-lambda-function \
    --runtime python3.9 \
    --role arn:aws:iam::123456789012:role/lambda-execution-role \
    --handler lambda_function.lambda_handler \
    --zip-file fileb://function.zip \
    --description "My first Lambda function" \
    --timeout 30 \
    --memory-size 128 \
    --environment Variables='{ENV=production,DEBUG=false}' \
    --tags Project=WebApp,Environment=Production

# 从S3创建函数
aws lambda create-function \
    --function-name s3-lambda-function \
    --runtime nodejs18.x \
    --role arn:aws:iam::123456789012:role/lambda-execution-role \
    --handler index.handler \
    --code S3Bucket=my-lambda-bucket,S3Key=function.zip \
    --timeout 60 \
    --memory-size 256

2. 列出Lambda函数

# 列出所有函数
aws lambda list-functions

# 列出函数(简化输出)
aws lambda list-functions \
    --query 'Functions[*].{Name:FunctionName,Runtime:Runtime,LastModified:LastModified}' \
    --output table

# 按运行时筛选
aws lambda list-functions \
    --query 'Functions[?Runtime==`python3.9`].{Name:FunctionName,Size:CodeSize}'

3. 获取函数信息

# 获取函数配置
aws lambda get-function-configuration \
    --function-name my-lambda-function

# 获取函数详细信息
aws lambda get-function \
    --function-name my-lambda-function

# 获取函数的代码签名配置
aws lambda get-function-code-signing-config \
    --function-name my-lambda-function

获取函数代码并下载

Windows环境下载函数代码

REM 方法1:直接下载到当前目录
aws lambda get-function ^
    --function-name my-lambda-function ^
    --query "Code.Location" ^
    --output text > temp_url.txt

REM 使用PowerShell下载
powershell -Command "Invoke-WebRequest -Uri (Get-Content temp_url.txt) -OutFile function-code.zip"

REM 清理临时文件
del temp_url.txt

REM 解压代码
powershell -Command "Expand-Archive -Path function-code.zip -DestinationPath ./function-source -Force"

REM 方法2:使用PowerShell一键下载
powershell -Command "$url = aws lambda get-function --function-name my-lambda-function --query 'Code.Location' --output text; Invoke-WebRequest -Uri $url -OutFile 'function-code.zip'; Expand-Archive -Path 'function-code.zip' -DestinationPath './function-source' -Force"

REM 方法3:批量下载多个函数
for /f "tokens=*" %%i in ('aws lambda list-functions --query "Functions[*].FunctionName" --output text') do (
    echo Downloading function: %%i
    powershell -Command "$url = aws lambda get-function --function-name %%i --query 'Code.Location' --output text; Invoke-WebRequest -Uri $url -OutFile '%%i-code.zip'"
)

Linux环境下载函数代码

# 方法1:使用curl下载
FUNCTION_NAME="my-lambda-function"
DOWNLOAD_URL=$(aws lambda get-function \
    --function-name $FUNCTION_NAME \
    --query "Code.Location" \
    --output text)

curl -o "${FUNCTION_NAME}-code.zip" "$DOWNLOAD_URL"

# 解压代码
unzip "${FUNCTION_NAME}-code.zip" -d "./function-source/"

# 方法2:使用wget下载
wget -O "${FUNCTION_NAME}-code.zip" "$DOWNLOAD_URL"

# 方法3:一键下载脚本
#!/bin/bash
download_lambda_code() {
    local function_name=$1
    local output_dir=${2:-"./lambda-downloads"}
    
    echo "Downloading code for function: $function_name"
    
    # 创建输出目录
    mkdir -p "$output_dir"
    
    # 获取下载URL
    local download_url=$(aws lambda get-function \
        --function-name "$function_name" \
        --query "Code.Location" \
        --output text)
    
    if [ $? -eq 0 ] && [ -n "$download_url" ]; then
        # 下载代码
        curl -s -o "$output_dir/${function_name}-code.zip" "$download_url"
        
        # 解压到专用目录
        mkdir -p "$output_dir/$function_name"
        unzip -q "$output_dir/${function_name}-code.zip" -d "$output_dir/$function_name/"
        
        echo "Code downloaded and extracted to: $output_dir/$function_name"
    else
        echo "Failed to get download URL for function: $function_name"
    fi
}

# 使用示例
download_lambda_code "my-lambda-function"

# 方法4:批量下载所有函数
#!/bin/bash
download_all_lambda_functions() {
    local output_dir=${1:-"./all-lambda-functions"}
    
    echo "Downloading all Lambda functions..."
    mkdir -p "$output_dir"
    
    # 获取所有函数名称
    aws lambda list-functions \
        --query "Functions[*].FunctionName" \
        --output text | tr '\t' '\n' | while read function_name; do
        
        if [ -n "$function_name" ]; then
            echo "Processing: $function_name"
            
            # 获取下载URL
            download_url=$(aws lambda get-function \
                --function-name "$function_name" \
                --query "Code.Location" \
                --output text 2>/dev/null)
            
            if [ $? -eq 0 ] && [ -n "$download_url" ]; then
                # 下载并解压
                curl -s -o "$output_dir/${function_name}-code.zip" "$download_url"
                mkdir -p "$output_dir/$function_name"
                unzip -q "$output_dir/${function_name}-code.zip" -d "$output_dir/$function_name/" 2>/dev/null
                rm "$output_dir/${function_name}-code.zip"
                echo "✓ Downloaded: $function_name"
            else
                echo "✗ Failed: $function_name"
            fi
        fi
    done
    
    echo "All functions downloaded to: $output_dir"
}

# 执行批量下载
download_all_lambda_functions

高级下载选项

# 下载特定版本的函数代码
aws lambda get-function \
    --function-name my-lambda-function \
    --qualifier "2" \
    --query "Code.Location" \
    --output text

# 下载函数的别名版本
aws lambda get-function \
    --function-name my-lambda-function \
    --qualifier "PROD" \
    --query "Code.Location" \
    --output text

# 获取函数代码的SHA256哈希值
aws lambda get-function \
    --function-name my-lambda-function \
    --query "Configuration.CodeSha256" \
    --output text

# 比较本地代码和远程代码
LOCAL_HASH=$(sha256sum function.zip | cut -d' ' -f1)
REMOTE_HASH=$(aws lambda get-function-configuration \
    --function-name my-lambda-function \
    --query "CodeSha256" \
    --output text)

if [ "$LOCAL_HASH" = "$REMOTE_HASH" ]; then
    echo "Code is up to date"
else
    echo "Code differs from deployed version"
fi

更新Lambda函数

1. 更新函数代码

# 从ZIP文件更新
aws lambda update-function-code \
    --function-name my-lambda-function \
    --zip-file fileb://updated-function.zip

# 从S3更新
aws lambda update-function-code \
    --function-name my-lambda-function \
    --s3-bucket my-lambda-bucket \
    --s3-key updated-function.zip

# 更新容器镜像
aws lambda update-function-code \
    --function-name my-container-function \
    --image-uri 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-lambda:latest

2. 更新函数配置

# 更新运行时和处理程序
aws lambda update-function-configuration \
    --function-name my-lambda-function \
    --runtime python3.11 \
    --handler new_module.handler \
    --timeout 60 \
    --memory-size 256

# 更新环境变量
aws lambda update-function-configuration \
    --function-name my-lambda-function \
    --environment Variables='{ENV=staging,DEBUG=true,API_KEY=new-key}'

# 更新VPC配置
aws lambda update-function-configuration \
    --function-name my-lambda-function \
    --vpc-config SubnetIds=subnet-12345,subnet-67890,SecurityGroupIds=sg-12345678

函数版本和别名管理

1. 版本管理

# 发布新版本
aws lambda publish-version \
    --function-name my-lambda-function \
    --description "Version with bug fixes"

# 列出所有版本
aws lambda list-versions-by-function \
    --function-name my-lambda-function

# 获取特定版本信息
aws lambda get-function \
    --function-name my-lambda-function \
    --qualifier "2"

2. 别名管理

# 创建别名
aws lambda create-alias \
    --function-name my-lambda-function \
    --name PROD \
    --function-version "2" \
    --description "Production alias"

# 更新别名
aws lambda update-alias \
    --function-name my-lambda-function \
    --name PROD \
    --function-version "3"

# 列出别名
aws lambda list-aliases \
    --function-name my-lambda-function

调用Lambda函数

1. 同步调用

# 同步调用函数
aws lambda invoke \
    --function-name my-lambda-function \
    --payload '{"key1":"value1","key2":"value2"}' \
    --cli-binary-format raw-in-base64-out \
    response.json

# 查看响应
cat response.json

# 调用特定版本
aws lambda invoke \
    --function-name my-lambda-function \
    --qualifier "PROD" \
    --payload '{"test":"data"}' \
    --cli-binary-format raw-in-base64-out \
    prod-response.json

2. 异步调用

# 异步调用
aws lambda invoke \
    --function-name my-lambda-function \
    --invocation-type Event \
    --payload '{"async":"true"}' \
    --cli-binary-format raw-in-base64-out \
    async-response.json

# 干运行(验证参数和权限)
aws lambda invoke \
    --function-name my-lambda-function \
    --invocation-type DryRun \
    --payload '{"test":"validation"}' \
    --cli-binary-format raw-in-base64-out \
    dryrun-response.json

事件源映射

1. 创建事件源映射

# SQS事件源
aws lambda create-event-source-mapping \
    --function-name my-lambda-function \
    --event-source-arn arn:aws:sqs:us-east-1:123456789012:my-queue \
    --batch-size 10 \
    --maximum-batching-window-in-seconds 5

# Kinesis事件源
aws lambda create-event-source-mapping \
    --function-name my-lambda-function \
    --event-source-arn arn:aws:kinesis:us-east-1:123456789012:stream/my-stream \
    --starting-position LATEST \
    --batch-size 100

# DynamoDB Streams事件源
aws lambda create-event-source-mapping \
    --function-name my-lambda-function \
    --event-source-arn arn:aws:dynamodb:us-east-1:123456789012:table/my-table/stream/2023-01-01T00:00:00.000 \
    --starting-position TRIM_HORIZON

2. 管理事件源映射

# 列出事件源映射
aws lambda list-event-source-mappings \
    --function-name my-lambda-function

# 更新事件源映射
aws lambda update-event-source-mapping \
    --uuid 12345678-1234-1234-1234-123456789012 \
    --batch-size 50 \
    --maximum-batching-window-in-seconds 10

# 删除事件源映射
aws lambda delete-event-source-mapping \
    --uuid 12345678-1234-1234-1234-123456789012

权限管理

1. 资源策略

# 添加权限
aws lambda add-permission \
    --function-name my-lambda-function \
    --statement-id allow-s3-invoke \
    --action lambda:InvokeFunction \
    --principal s3.amazonaws.com \
    --source-arn arn:aws:s3:::my-bucket

# 获取策略
aws lambda get-policy \
    --function-name my-lambda-function

# 删除权限
aws lambda remove-permission \
    --function-name my-lambda-function \
    --statement-id allow-s3-invoke

2. 执行角色

# 更新执行角色
aws lambda update-function-configuration \
    --function-name my-lambda-function \
    --role arn:aws:iam::123456789012:role/new-lambda-role

# 获取当前角色
aws lambda get-function-configuration \
    --function-name my-lambda-function \
    --query "Role" \
    --output text

监控和日志

1. CloudWatch日志

# 获取日志组
aws logs describe-log-groups \
    --log-group-name-prefix "/aws/lambda/my-lambda-function"

# 获取最新日志
aws logs describe-log-streams \
    --log-group-name "/aws/lambda/my-lambda-function" \
    --order-by LastEventTime \
    --descending \
    --max-items 1

# 获取日志事件
aws logs get-log-events \
    --log-group-name "/aws/lambda/my-lambda-function" \
    --log-stream-name "2023/12/01/[\$LATEST]abcd1234" \
    --start-time 1701388800000

2. 指标和监控

# 获取函数指标
aws cloudwatch get-metric-statistics \
    --namespace AWS/Lambda \
    --metric-name Invocations \
    --dimensions Name=FunctionName,Value=my-lambda-function \
    --start-time 2023-12-01T00:00:00Z \
    --end-time 2023-12-01T23:59:59Z \
    --period 3600 \
    --statistics Sum

# 获取错误率
aws cloudwatch get-metric-statistics \
    --namespace AWS/Lambda \
    --metric-name Errors \
    --dimensions Name=FunctionName,Value=my-lambda-function \
    --start-time 2023-12-01T00:00:00Z \
    --end-time 2023-12-01T23:59:59Z \
    --period 3600 \
    --statistics Sum

层(Layers)管理

1. 创建和管理层

# 创建层
aws lambda publish-layer-version \
    --layer-name my-python-layer \
    --description "Common Python libraries" \
    --zip-file fileb://layer.zip \
    --compatible-runtimes python3.9 python3.11

# 列出层版本
aws lambda list-layer-versions \
    --layer-name my-python-layer

# 获取层信息
aws lambda get-layer-version \
    --layer-name my-python-layer \
    --version-number 1

# 删除层版本
aws lambda delete-layer-version \
    --layer-name my-python-layer \
    --version-number 1

2. 在函数中使用层

# 添加层到函数
aws lambda update-function-configuration \
    --function-name my-lambda-function \
    --layers arn:aws:lambda:us-east-1:123456789012:layer:my-python-layer:1 \
            arn:aws:lambda:us-east-1:123456789012:layer:another-layer:2

# 移除所有层
aws lambda update-function-configuration \
    --function-name my-lambda-function \
    --layers

实际应用案例

案例1:自动化部署脚本

#!/bin/bash
# Lambda函数自动化部署脚本

FUNCTION_NAME="web-api-handler"
ROLE_ARN="arn:aws:iam::123456789012:role/lambda-execution-role"
RUNTIME="python3.11"
HANDLER="app.lambda_handler"

# 1. 打包代码
echo "Packaging function code..."
zip -r function.zip . -x "*.git*" "*.pyc" "__pycache__/*" "tests/*"

# 2. 检查函数是否存在
if aws lambda get-function --function-name $FUNCTION_NAME >/dev/null 2>&1; then
    echo "Function exists, updating code..."
    aws lambda update-function-code \
        --function-name $FUNCTION_NAME \
        --zip-file fileb://function.zip
    
    echo "Updating configuration..."
    aws lambda update-function-configuration \
        --function-name $FUNCTION_NAME \
        --runtime $RUNTIME \
        --handler $HANDLER \
        --timeout 30 \
        --memory-size 256
else
    echo "Creating new function..."
    aws lambda create-function \
        --function-name $FUNCTION_NAME \
        --runtime $RUNTIME \
        --role $ROLE_ARN \
        --handler $HANDLER \
        --zip-file fileb://function.zip \
        --timeout 30 \
        --memory-size 256 \
        --environment Variables='{ENV=production}'
fi

# 3. 发布新版本
echo "Publishing new version..."
VERSION=$(aws lambda publish-version \
    --function-name $FUNCTION_NAME \
    --description "Deployed on $(date)" \
    --query "Version" \
    --output text)

echo "Published version: $VERSION"

# 4. 更新PROD别名
echo "Updating PROD alias..."
aws lambda update-alias \
    --function-name $FUNCTION_NAME \
    --name PROD \
    --function-version $VERSION

# 5. 测试函数
echo "Testing function..."
aws lambda invoke \
    --function-name $FUNCTION_NAME \
    --qualifier PROD \
    --payload '{"test": true}' \
    --cli-binary-format raw-in-base64-out \
    test-response.json

echo "Deployment completed successfully!"

案例2:批量函数管理

#!/bin/bash
# 批量Lambda函数管理脚本

# 批量更新函数运行时
update_runtime() {
    local old_runtime=$1
    local new_runtime=$2
    
    echo "Updating functions from $old_runtime to $new_runtime..."
    
    aws lambda list-functions \
        --query "Functions[?Runtime=='$old_runtime'].FunctionName" \
        --output text | tr '\t' '\n' | while read function_name; do
        
        if [ -n "$function_name" ]; then
            echo "Updating $function_name..."
            aws lambda update-function-configuration \
                --function-name "$function_name" \
                --runtime "$new_runtime"
        fi
    done
}

# 批量添加标签
add_tags_to_functions() {
    local tag_key=$1
    local tag_value=$2
    
    echo "Adding tag $tag_key=$tag_value to all functions..."
    
    aws lambda list-functions \
        --query "Functions[*].FunctionName" \
        --output text | tr '\t' '\n' | while read function_name; do
        
        if [ -n "$function_name" ]; then
            aws lambda tag-resource \
                --resource "arn:aws:lambda:$(aws configure get region):$(aws sts get-caller-identity --query Account --output text):function:$function_name" \
                --tags "$tag_key=$tag_value"
        fi
    done
}

# 批量备份函数代码
backup_all_functions() {
    local backup_dir=${1:-"./lambda-backup-$(date +%Y%m%d)"}
    
    echo "Backing up all Lambda functions to $backup_dir..."
    mkdir -p "$backup_dir"
    
    aws lambda list-functions \
        --query "Functions[*].{Name:FunctionName,Runtime:Runtime}" \
        --output json > "$backup_dir/functions-list.json"
    
    aws lambda list-functions \
        --query "Functions[*].FunctionName" \
        --output text | tr '\t' '\n' | while read function_name; do
        
        if [ -n "$function_name" ]; then
            echo "Backing up $function_name..."
            
            # 备份配置
            aws lambda get-function-configuration \
                --function-name "$function_name" > "$backup_dir/${function_name}-config.json"
            
            # 下载代码
            download_url=$(aws lambda get-function \
                --function-name "$function_name" \
                --query "Code.Location" \
                --output text)
            
            if [ -n "$download_url" ]; then
                curl -s -o "$backup_dir/${function_name}-code.zip" "$download_url"
            fi
        fi
    done
    
    echo "Backup completed in $backup_dir"
}

# 使用示例
# update_runtime "python3.8" "python3.11"
# add_tags_to_functions "Environment" "Production"
# backup_all_functions

删除Lambda资源

# 删除函数
aws lambda delete-function \
    --function-name my-lambda-function

# 删除特定版本(不能删除$LATEST)
aws lambda delete-function \
    --function-name my-lambda-function \
    --qualifier "2"

# 删除别名
aws lambda delete-alias \
    --function-name my-lambda-function \
    --name STAGING

# 删除层版本
aws lambda delete-layer-version \
    --layer-name my-layer \
    --version-number 1

总结

核心优势

  1. 无服务器架构

    • 无需管理服务器

    • 自动扩展

    • 按使用量付费

  2. 丰富的集成

    • 与AWS服务深度集成

    • 支持多种触发器

    • 事件驱动架构

  3. 开发效率

    • 快速部署

    • 版本管理

    • 内置监控

最佳实践

  1. 代码管理

    • 使用版本控制

    • 定期备份函数代码

    • 合理使用层减少重复

  2. 性能优化

    • 合理设置内存大小

    • 优化冷启动时间

    • 使用预留并发

  3. 安全配置

    • 最小权限原则

    • 使用VPC隔离

    • 定期轮换密钥

  4. 监控运维

    • 配置CloudWatch告警

    • 使用X-Ray追踪

    • 定期检查日志

AWS Lambda通过CLI提供了完整的函数生命周期管理能力,从代码下载到部署监控,为无服务器应用开发提供了强大的工具支持。