aws sam 本地测试部署 lambda 和 apigateway

news2025/2/24 18:07:26

使用sam框架可以在部署serverless应用之前,在本地调试application是否符合预期

sam框架安装

serverless应用是lambda函数,事件源和其他资源的组合

使用sam能够基于docker容器在本地测试lambda函数

安装sam

wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
sudo ./sam-installation/install --update
sam --version

示例程序中三个比较重要的文件

 sam-app/
   ├── README.md
   ├── events/
   │   └── event.json
   ├── hello_world/
   │   ├── __init__.py
   │   ├── app.py            #Contains your AWS Lambda handler logic.
   │   └── requirements.txt  #Contains any Python dependencies the application requires, used for sam build
   ├── template.yaml         #Contains the AWS SAM template defining your application's AWS resources.
   └── tests/
       └── unit/
           ├── __init__.py
           └── test_handler.py
  • template.yaml:包含Amazon SAM定义应用程序的模板Amazon资源的费用
  • hello_world/app.py:包含实际的 Lambda 处理程序逻辑
  • hello_world/requirements.txt:包含应用程序所需的任何 Python 依赖项,用于sam build

测试和调试serverless

测试和调试无服务器应用程序

本地调用lambda

sam local invoke对应lambda命令aws lambda invoke

$ sam local invoke "Ratings" -e event.json
$ echo '{"message": "Hey, are you there?" }' | sam local invoke --event - "Ratings"

注意:如果函数包含layer,本地调用或测试时层包将下载并缓存在本地

sam本地调用主要通过template.yaml识别函数

$ sam build
Build Succeeded
Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

使用官方image构建lambda镜像,将构建完毕的

$ echo '{"message": "Hey, are you there?" }' | sam local invoke "HelloWorldFunction"
Invoking app.lambda_handler (python3.7)
Image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.7
Building image.....
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.7:rapid-1.66.0-x86_64.

Mounting xxxxx/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: c95f8298-2ff8-4eed-ab34-8ba730ac62f1 Version: $LATEST
END RequestId: c95f8298-2ff8-4eed-ab34-8ba730ac62f1
REPORT RequestId: c95f8298-2ff8-4eed-ab34-8ba730ac62f1  Init Duration: 2.54 ms  Duration: 111.97 ms     Billed Duration: 112 ms      Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}
SAM CLI update available (1.68.0); (1.66.0 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

本地调用apigateway

使用sam local start-api在本地启动api,可以热重载。sam识别template.yaml模板中。

默认sam使用lambda代理集成,并支持http api 和 rest api

示例程序如下

import json
import requests

def lambda_handler(event, context):
    try:
        ip = requests.get("http://checkip.amazonaws.com/")
    except requests.RequestException as e:
        print(e)
        raise e
    
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
            "location": ip.text.replace("\n", "")
        }),
    }

示例模板如下

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: rating app
Globals:
  Function:
    Timeout: 3
    MemorySize: 128
Resources:
  Ratings:
    Type: AWS::Serverless::Function
    Properties:
      Handler: ratings.lambda_handler
      Runtime: python3.7
      Architectures:
      - x86_64
      Events:
        Api:
          Type: Api
          Properties:
            Path: /ratings
            Method: get
      CodeUri: Ratings
    Metadata:
      SamResourceId: Ratings

当访问对应的api时,会启动构建,并将代码通过挂载卷的方式挂载到容器中

$ sam local start-api
Mounting Ratings at http://127.0.0.1:3000/ratings [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
2023-01-09 15:19:21  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking ratings.lambda_handler (python3.7)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.7:rapid-1.66.0-x86_64.

Mounting /home/ec2-user/efs/aws-sam-test/ratingdemo/.aws-sam/build/Ratings as /var/task:ro,delegated inside runtime container
START RequestId: a5b6a479-c011-4139-b142-98c0e88a0e6c Version: $LATEST
END RequestId: a5b6a479-c011-4139-b142-98c0e88a0e6c
REPORT RequestId: a5b6a479-c011-4139-b142-98c0e88a0e6c  Init Duration: 0.13 ms  Duration: 592.02 ms     Billed Duration: 593 ms  Memory Size: 128 MB     Max Memory Used: 128 MB
No Content-Type given. Defaulting to 'application/json'.
2023-01-09 15:19:25 127.0.0.1 - - [09/Jan/2023 15:19:25] "GET /ratings HTTP/1.1" 200 -

此外,sam还提供了模拟lambda终端节点,生成模拟事件的命令

sam local start-lambda
sam local generate-event s3 put

可以使用vscode插件方便管理和编写lambda函数

https://docs.aws.amazon.com/zh_cn/toolkit-for-vscode/latest/userguide/remote-lambda.html

sam集成codedeploy部署lambda

使 Lambda 码部署和Amazon无服务器应用程序模型

将应用程序规范文件添加到 CodeDeploy 的 revision

sam本身能够将将代码打包为lambda函数,并通过蓝绿部署的方式发布。sam使用cloudformation创建lambda函数和codedeploy,同时完成版本切换和蓝绿发布

打包并部署命令如下

sam package \
  --template-file template.yml \
  --output-template-file package.yml \
  --s3-bucket s3://xxxxx/xxxx
  
$ sam deploy \
  --template-file package.yml \
  --stack-name my-date-time-app \
  --capabilities CAPABILITY_IAM

实例代码的template.yaml文件,注释的非常清楚,需要注意以下几点

  • 函数的资源类型为AWS::Serverless::Function,AWS::Serverless是cloudformation提供的官方宏,实质是对lambda函数写法的简化,cfn会将模板转换并扩展为兼容的cfn模板

    AWSTemplateFormatVersion : '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
    Resources:
      myDateTimeFunction:
        Type: AWS::Serverless::Function
        Properties:
          Handler: myDateTimeFunction.handler
          Runtime: nodejs16.x
          AutoPublishAlias: live
    	  ...
          DeploymentPreference:  
              Type: Linear10PercentEvery1Minute
              Hooks:
                PreTraffic: !Ref beforeAllowTraffic
                PostTraffic: !Ref afterAllowTraffic
    
  • 当在serverless中指定AutoPublishAlias时,lambda函数会创建alias,检测函数变化并通过名为live的别名部署

  • DeploymentPreference是独属于sam的属性,启用该属性后转换的cfn模板会创建codedeploy 应用,部署组和角色对lambda,同时可以在hook中指定流量切换前后的测试函数。测试函数在lambda控制台上显示为关联函数

在这里插入图片描述

测试函数的主要逻辑在于

  • 调用主函数(函数名通过环境变量传入)
  • 将调用结果回传codedeploy(需要使用事件中的deploymentId和lifecycleEventHookExecutionId参数)
'use strict';
const AWS = require('aws-sdk');
const codedeploy = new AWS.CodeDeploy({ apiVersion: '2014-10-06' });
var lambda = new AWS.Lambda();

exports.handler = (event, context, callback) => {
    console.log("Entering PreTraffic Hook!");
    var deploymentId = event.DeploymentId;
    var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;
    var functionToTest = process.env.NewVersion;
    var lambdaParams = {
        FunctionName: functionToTest,
        Payload: "{\"option\": \"time\"}",
        InvocationType: "RequestResponse"
    };
    var lambdaResult = "Failed";
    // Invoke the updated Lambda function.
    lambda.invoke(lambdaParams, function (err, data) {
        if (err) {	// an error occurred
            console.log(err, err.stack);
            lambdaResult = "Failed";
        }
        else {	// successful response
            var result = JSON.parse(data.Payload);
            console.log("Result: " + JSON.stringify(result));
            console.log("statusCode: " + result.statusCode);
            if (result.statusCode != "400") {
                console.log("Validation succeeded");
                lambdaResult = "Succeeded";
            }
            else {
                console.log("Validation failed");
            }

            var params = {
                deploymentId: deploymentId,
                lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
                status: lambdaResult
            };

            codedeploy.putLifecycleEventHookExecutionStatus(params, function (err, data) {
                if (err) {
                    // Validation failed.
                    console.log("CodeDeploy Status update failed");
                    console.log(err, err.stack);
                    callback("CodeDeploy Status update failed");
                } else {
                    // Validation succeeded.
                    console.log("CodeDeploy status updated successfully");
                    callback(null, "CodeDeploy status updated successfully");
                }
            });
        }
    });
}

生成的codedeploy修订如下,即通过将别名指向不同版本完成流量切换

{
  "version": "0.0",
  "Resources": [
    {
      "my-date-time-app-myDateTimeFunction-L7EvikmOAZm9": {
        "Type": "AWS::Lambda::Function",
        "Properties": {
          "Name": "my-date-time-app-myDateTimeFunction-L7EvikmOAZm9",
          "Alias": "live",
          "CurrentVersion": "1",
          "TargetVersion": "2"
        }
      }
    }
  ],
  "Hooks": [
    {
      "BeforeAllowTraffic": "CodeDeployHook_beforeAllowTraffic"
    },
    {
      "AfterAllowTraffic": "CodeDeployHook_afterAllowTraffic"
    }
  ]
}
  • serverless模板转换后的serverless函数会转化成普通的lambda函数资源,通过alias资源的update策略,当函数版本变化时触发codedeploy操作

      myDateTimeFunctionAliaslive:
        Type: 'AWS::Lambda::Alias'
        UpdatePolicy:
          CodeDeployLambdaAliasUpdate:
            ApplicationName:
              Ref: ServerlessDeploymentApplication
            DeploymentGroupName:
              Ref: myDateTimeFunctionDeploymentGroup
            BeforeAllowTrafficHook:
              Ref: beforeAllowTraffic
            AfterAllowTrafficHook:
              Ref: afterAllowTraffic
        Properties:
          Name: live
          FunctionName:
            Ref: myDateTimeFunction
          FunctionVersion:
            'Fn::GetAtt':
              - myDateTimeFunctionVersion368eb951f6
              - Version
    
  • 部署配置为Linear10PercentEvery1Minute,即codedeploy的流量切换为线性每分钟切换10%

    img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/151740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ArcGIS基础实验操作100例--实验77按要素分区统计路网

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台:ArcGIS 10.6 实验数据:请访问实验1(传送门) 高级编辑篇--实验77 按要素分区统计路网 目录 一、实验背景 二、实验数据 三、实验步骤 (…

ART-SLAM: Accurate Real-Time 6DoF LiDAR SLAM

IEEE Robotics and Automation Letters 意大利米兰理工学院 Abstract 地面车辆实时六自由度姿态估计,由于自动驾驶和三维建图等诸多应用,是机器人技术中一个相关和被研究广泛的课题。虽然有些系统已经存在,但它们要么不够准确,要…

Qt之标准对话框(QMessageBox、QFileDialog)

文章目录前言如何学习标准对话框QMessageBox消息对话框应用属性实操QFileDialog文件对话框应用属性实操前言 Qt为开发者提供了一些可复用的对话框,他对我们的开发是很重要的。下面我们就来学习 提示:以下是本篇文章正文内容,下面案例可供参考…

无监控,不运维!深入浅出介绍ChengYing监控设计和使用

监控系统俗称「第三只眼」,几乎是我们每天都会打交道的系统,它也一直是IT系统中的核心组成部分,负责问题的发现以及辅助性的定位。 ChengYing作为一站式全自动化全生命周期大数据平台运维管家,自然也提供大数据产品的监控服务。这…

力扣sql基础篇(二)

力扣sql基础篇(二) 1 每月交易I 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # sum函数如果需要筛选,可以考虑在里面嵌套if函数 SELECT DATE_FORMAT(trans_date,"%Y-%m") month,country,count(*) trans_count,COUNT(IF(state"appr…

matlab利用逻辑数组将保密率负数部分转换为零

通信中计算保密率的公式为 r[Rd−Re]r[R_d-R_e]^ r[Rd​−Re​] 其中RdR_dRd​代表合法目的地的数据速率,ReR_eRe​代表窃听节点的数据速率 当窃听节点的速率大于目的节点的速率时候,计算出来的保密率是负值,这在设计的时候可以将这时候的保…

referer、prototype、array、json笔记整理

目录referer、prototype、array、json笔记整理refererReferrer-policy如何设置referer绕过图片防盗链1、利用https网站盗链http资源网站,refer不会发送2、设置meta3、设置referrerpolicy"no-referrer"4、利用iframe伪造请求referer5、客户端在请求时修改h…

【LeetCode每日一题】——233.数字 1 的个数

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 数学 二【题目难度】 困难 三【题目编号】 233.数字 1 的个数 四【题目描述】 给定一个整数 …

为你的Typecho使用Redis缓存,优化访问速度-织音博客

前言Typecho虽然轻量,但终究仍是PHP动态脚本,访问时需要频繁调取数据库的信息,导致并发值一高,CPU就100%占用,无法处理新的请求信息。这时,我们可以用Redis来设置缓存,从而不用频繁调动数据库&a…

【Meetup预告】SeaTunnel + OpenMLDB:共筑数据集成生态,加速实时场景落地

2023年1月12日(周四)20:00-21:30,云原生数据集成平台 SeaTunnel 联合开源机器学习数据库 OpenMLDB 合作带来本期 Meetup。 活动背景 Al 应用的繁荣发展,既得益于数据的爆发式增长,也受困于数据治理的种种…

使用Bokeh进行数据可视化的8个建议(上)

使用 Bokeh 库创建数据可视化的快速提示和示例。 长按关注《Python学研大本营》,加入读者群,分享更多精彩 扫码关注《Python学研大本营》,加入读者群,分享更多精彩 Python 是创建数据可视化的绝佳开源工具。有许多可用的数据可视…

JavaWeb:会话技术之Cookie

1,会话跟踪技术的概述 对于会话跟踪这四个词,我们需要拆开来进行解释,首先要理解什么是会话,然后再去理解什么是会话跟踪: 会话:用户打开浏览器,访问web服务器的资源,会话建立&…

设计模式-到底什么是builder模式

我们来看一个一些常见的开源代码中带builder字样的经典类:(jdk)Stringbuilder(spring)springApplicationBuilder(es)xxxQuerybulider如果只去看这些类的话,应该是一团乱码&#xff0…

【Kotlin】字符串操作 ① ( 截取字符串函数 substring | 拆分字符串函数 split | 解构语法特性 )

文章目录一、截取字符串函数 substring二、拆分字符串函数 split一、截取字符串函数 substring Kotlin 中提供了 截取字符串函数 substring , 可接收 IntRange 类型的参数 , 这是 整数范围 类型 ; 截取字符串函数 substring 函数原型为 : /*** 返回由给定的[range]索引指定的…

【pat】网红点打卡攻略【图】

一个旅游景点,如果被带火了的话,就被称为“网红点”。大家来网红点游玩,俗称“打卡”。在各个网红点打卡的快(省)乐(钱)方法称为“攻略”。你的任务就是从一大堆攻略中,找出那个能在…

【MyBatis】第一篇:初体验

还是老规矩看一下百度百科中的解释: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息&#xff0c…

Web(三)

JavaScript基础概念:一门客户端脚本语言* 运行在客户端浏览器中的。每一个浏览器都有JavaScript的解析引擎* 脚本语言:不需要编译,直接就可以被浏览器解析执行了功能:* 可以来增强用户和html页面的交互过程,可以来控制…

蓝桥杯C51

#include "reg52.h"sfr AUXR 0x8e; //定义辅助寄存器sbit S5 P3^2; //定义按键S5引脚 sbit S4 P3^3; //定义按键S4引脚unsigned char count 0; //定义中断计数器 unsigned char t_h 0; //定义运行时间的变量 unsigned char t_m 0; …

Struts2之OGNL表达式

Struts2之OGNL表达式1、什么是OGNL表达式2、OGNL表达式的作用3、值栈与OGNL3.1、值栈3.2、OGNL访问值栈4、类型转换4.1、类型转换的意义4.2、内置的类型转换器4.3、自定义类型转换器4.3.1、创建日期转换器4.3.2、配置转换器4.3.3、页面4.3.4、实体类和Action控制器4.3.5、strut…

从0到1完成一个Vue后台管理项目(七、Header、Footer、页面布局)

往期 从0到1完成一个Vue后台管理项目(一、创建项目) 从0到1完成一个Vue后台管理项目(二、使用element-ui) 从0到1完成一个Vue后台管理项目(三、使用SCSS/LESS,安装图标库) 从0到1完成一个Vu…