AWS Lambda实际应用。第2部分:了解开发和测试工具



本指南是在开发和测试无服务器应用程序方面的个人经验的结果,以及在尝试对拐杖和自行车进行操纵时的个人经验。当我刚开始开发无服务器应用程序时,我不得不动手解决所有问题,没有用于本地开发和测试的明确指南或便捷工具。

现在情况正在发生变化:工具开始出现,但是要找到使用它们的手册并不容易。在本文中,我将通过一个简单的示例演示如何使用新功能。您可以轻松掌握它并解决那些我很幸运遇到的问题和错误。

您将学习如何使用AWS,SAM-CLI和IntelljIDEA浏览器控制台进行开发。我还将讨论测试:集成,端到端和单元测试。最后,我们将讨论这种解决方案的成本(破坏者:您可以节省很多钱)。

本文对那些开始开发无服务器应用程序但还不熟悉其工具和方法的人很有用。


将讨论什么


大家好!我的名字叫Alexander Gruzdev,我很高兴介绍有关基于AWS Lambda的无服务器解决方案的使用和开发的文章的第二部分。在后续文章中,我们将从第一部分开始讨论开发和测试解决方案的方法(Java 11中的AWS Lambda in Action。我们在“生产”中访问Serverless)。

自从上一篇文章发表以来,已经对测试应用程序进行了稍微的重新设计,但是主要含义保持不变。这是一个简单的HTML表单“联系我们”,该表单通过HTTP请求将数据从表单发送到Gateway API,然后将处理请求代理到AWS Lambda。在处理期间,lambda将数据写入DynamoDB表,并通过AWS SES发送一封信。组件图如下所示。

组件图


内容


  1. 使用AWS Browser控制台进行开发
  2. 使用SAM-CLI进行开发
  3. 使用IntelljIDEA进行开发
  4. 测试类型
  5. 无服务器成本
  6. 有用的链接



1.使用AWS浏览器控制台进行开发



AWS控制台


AWS控制台提供对任何AWS服务的访问,无论是您的虚拟EC2服务器,IAM还是AWS Lambda角色/访问策略设置,其所有参数都可以实时更改,而无需通过持续交付/持续部署系统进行重新部署。

这大大加快了开发过程和某些类型的测试。它还有助于直观地控制应用程序的启动和操作参数。

API网关控制台


该控制台使您可以监视应用程序的当前状态,管理环境并提供新版本。我将展示如何将其用于验证环境的健康状况。

让我们在“联系我们”应用程序的“资源”选项卡的屏幕快照中看一下这个“魔术”控制台的外观: 屏幕快照显示了如何通过POST API调用客户端通过Gateway API的请求进入lambda以及如何将响应返回给客户端。

网关资源



  • 方法请求 -处理请求的第一步。在我们的情况下,它不包含任何设置,但可能包含例如授权设置。
  • 集成请求意味着HTTP请求将以特殊格式传输到lambda:它包含客户端发送的所有信息以及有关被调用上下文的详细信息。
  • 集成响应表示HTTP客户端将直接从lambda接收响应。因此,您自己负责在lambda中形成响应主体。


禁用代理集成
API Gateway , Use Lambda Proxy integration Integration Request. . , , .


整合要求范例
SAM init events, , Integration request. , AWS , . AWS Lambda.


按下测试按钮以验证该应用程序正在运行。这将使您可以访问HTTP网关API调用。

在以下屏幕截图中,我发送了一个预热lambda的请求: 除了响应该请求之外,Gateway API还显示详细的日志。以相同的方式,您可以通过以以下形式替换JSON请求主体来发出真实请求:
网关测试请求


{
    "subject": "Email subject",
    "question": "Your question…",
    "username": "Your name…",
    "phone": "Your phone…",
    "email": "Your email…"
} 


因此,您可以在没有任何UI表单和前端应用程序的情况下手动测试您的API,从而分离前端和后端开发。作为内置控制台的替代,您可以使用Postman或任何其他HTTP客户端。

邮递员作为替代
HTTP- Postman. . , API Gateway AWS , API. , , AWS .


Lambda控制台


对于测试和开发,除了通过网关API的请求外,您还可以使用AWS Lambda浏览器控制台。

它的屏幕分为几个块:
  • Designer显示现有触发器和图层。在我们的例子中,触发器是API网关。如果单击它,将打开所有必要的信息:URL,阶段,资源路径。
  • 别名(在选择特定的lambda别名时可用)允许您配置按lambda版本划分的流量分配。下一节将对此进行更多介绍。
  • Function code — . zip- , . , Function code . Python/NodeJs.
  • Environment variables. , . , , . , . , , .
  • Tags — , , , , .
  • Execution role — ( ) , .
  • Basic settings — .
  • Network: - , VPC. — .
  • AWS X-Ray . AWS-.
  • Reserve concurrency , . .
    Provisioned concurrency
  • Provisioned concurrency — . , . , — . Free Tier .
  • 异步调用使您可以配置异步请求的特殊处理。我们指出发生错误时要进行多少次重复调用,以及请求可以在队列中挂起多长时间。(可选)您可以指定一个队列来处理失败的请求。

  • 数据库代理是另一个新功能,允许您以 API网关+ Lambda的形式配置通过代理对数据库的访问。


接下来,让我们看看如何从该控制台进行开发。除了更改参数之外,“ 配置测试事件”功能还可用于创建测试请求。有一个相当广泛的列表,但是我们将利用我已经在项目中附加的内容:
联系我们的要求
{
  "body": "{\"subject\": \"Question\",\"question\": \"How much does it cost\",\"username\": \"Alex\",\"phone\": \"+79999999999\",\"email\": \"alex@gmail.com\"}",
  "resource": "/{proxy+}",
  "path": "/path/to/resource",
  "httpMethod": "POST",
  "isBase64Encoded": false,
  "queryStringParameters": {
    "foo": "bar"
  },
  "pathParameters": {
    "proxy": "/path/to/resource"
  },
  "stageVariables": {
    "baz": "qux"
  },
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate, sdch",
    "Accept-Language": "en-US,en;q=0.8",
    "Cache-Control": "max-age=0",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-Country": "US",
    "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Custom User Agent String",
    "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
    "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
    "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "requestContext": {
    "accountId": "123456789012",
    "resourceId": "123456",
    "stage": "prod",
    "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "requestTime": "09/Apr/2015:12:34:56 +0000",
    "requestTimeEpoch": 1428582896000,
    "identity": {
      "cognitoIdentityPoolId": null,
      "accountId": null,
      "cognitoIdentityId": null,
      "caller": null,
      "accessKey": null,
      "sourceIp": "127.0.0.1",
      "cognitoAuthenticationType": null,
      "cognitoAuthenticationProvider": null,
      "userArn": null,
      "userAgent": "Custom User Agent String",
      "user": null
    },
    "path": "/prod/path/to/resource",
    "resourcePath": "/{proxy+}",
    "httpMethod": "POST",
    "apiId": "1234567890",
    "protocol": "HTTP/1.1"
  }
}


添加请求后,单击“ 测试”,然后查看lambda的结果: Lambda返回JSON,其中包含状态代码和响应正文。主体值将直接转到调用网关API的客户端。此外,屏幕截图还具有调用的特征:执行时间,我们将为其支付的执行时间,lambda消耗的最大内存量。依靠这些指标,我们可以配置最佳内存量,以便lambda符合您的价格/响应率要求。
网关资源



使用AWS控制台测试Canary部署


现在,让我们来谈谈与部署新版本的lambda有关的一个重要点。我在编写SAM模板时指定了以下参数:
AutoPublishAlias: live
DeploymentPreference:
  Type: Canary10Percent10Minutes

第一个参数自动为每个新版本的lambda添加一个的别名
关于别名的一点
, . , , API Gateway. 1, 2, 3 . LATEST, . 2 3 API Gateway (Stage AWS), Gateway-Lambda. API Gateway (ARN ), LATEST.

— ( ), , , ARN . , Stage API Gateway . , API Gateway: dev, qa prod .

, , . , . , live, . live- , , , , CloudWatch.


要测试金丝雀部署,可以同时使用Gateway API控制台和Lambda控制台。

首先,您需要更改lambda代码,以便它返回不同的答案。例如,在热身处理中,在响应中指定版本2而不是版本1,这将成为我们的标记。

现在,使用网关测试的API功能,我们可以确保在发送WARM-UP请求时的十分钟内,只有10%的响应在响应主体中具有版本2。在这段时间之后,版本2将返回100%的请求,

除了可以使用Gateway API控制台之外,我们还可以使用Lambda控制台,在该控制台中,选择了必要的别名后,我们会看到可以控制的流量分配策略。
Lambda别名



2.使用SAM-CLI进行本地开发


不久前,使用lambda的主要缺点之一被认为是在本地计算机上进行开发和测试带来的不便。现在情况发生了很大变化:SAM框架已经出现,它不仅可以收集和部署解决方案,还可以简化本地开发。

例如,您可以直接从控制台调用lambda:
sam local invoke -e ./events/warm_up_request.json ContactUsFunction

该命令从带有SAM模板的目录中启动,并将JSON文件的内容传输到输入lambda ContactUsFunction(这是模板中的逻辑名)。

也就是说,使用此命令,SAM在docker中生成镜像lambci / lambda:java11,并在其中运行代码。要访问诸如SES之类的远程服务,将使用带有密钥/访问密钥的AWS配置,因此它必须是最新的。另一个重要点:如果您不为热身模式添加标题,则将调用真实的AWS SES和DynamoDB服务。

在这里致电记录
F:\aws\projects\contact-us-sam-app>sam local invoke -e ./events/warm_up_request.json ContactUsFunction
Invoking com.gralll.sam.App::handleRequest (java11)
Fetching lambci/lambda:java11 Docker container image......
Mounting F:\aws\projects\contact-us-sam-app\.aws-sam\build\ContactUsFunction as /var/task:ro,delegated inside runtime container
?[32mSTART RequestId: a86d65fa-1f19-15c5-93b8-d87631c80ee2 Version: $LATEST?[0m
2020-01-06 19:09:17 a86d65fa-1f19-15c5-93b8-d87631c80ee2 INFO  App - Request was received
2020-01-06 19:09:17 a86d65fa-1f19-15c5-93b8-d87631c80ee2 DEBUG App - {
  "body" : "{\"subject\": \"Question\",\"question\": \"How much does it cost\",\"username\": \"Alex\",\"phone\": \"+79999999999\",\"email\": \"alex@gmail.com\"}",
  "resource" : "/{proxy+}",
  "requestContext" : {
    "resourceId" : "123456",
    "apiId" : "1234567890",
    "resourcePath" : "/{proxy+}",
    "httpMethod" : "POST",
    "requestId" : "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "extendedRequestId" : null,
    "accountId" : "123456789012",
    "identity" : {
      "apiKey" : null,
      "apiKeyId" : null,
      "userArn" : null,
      "cognitoAuthenticationType" : null,
      "caller" : null,
      "userAgent" : "Custom User Agent String",
      "user" : null,
      "cognitoIdentityPoolId" : null,
      "cognitoIdentityId" : null,
      "cognitoAuthenticationProvider" : null,
      "sourceIp" : "127.0.0.1",
      "accountId" : null,
      "accessKey" : null
    },
    "authorizer" : null,
    "stage" : "prod",
    "path" : "/prod/path/to/resource",
    "protocol" : "HTTP/1.1",
    "requestTime" : "09/Apr/2015:12:34:56 +0000",
    "requestTimeEpoch" : 1428582896000,
    "elb" : null
  },
  "multiValueQueryStringParameters" : { },
  "multiValueHeaders" : {
    "X-WARM-UP" : [ "13" ]
  },
  "pathParameters" : {
    "proxy" : "/path/to/resource"
  },
  "httpMethod" : "POST",
  "stageVariables" : {
    "baz" : "qux"
  },
  "path" : "/path/to/resource",
  "isBase64Encoded" : false,
  "requestSource" : "API_GATEWAY"
}
2020-01-06 19:09:17 a86d65fa-1f19-15c5-93b8-d87631c80ee2 INFO  App - Lambda was warmed up
?[32mEND RequestId: a86d65fa-1f19-15c5-93b8-d87631c80ee2?[0m
?[32mREPORT RequestId: a86d65fa-1f19-15c5-93b8-d87631c80ee2     Init Duration: 1984.55 ms       Duration: 42.22 ms      Billed Duration: 100 ms Memory Size: 256 MB     Max Memory Used: 102 MB ?[0m
{"statusCode":201,"multiValueHeaders":{"Access-Control-Allow-Origin":["*"]},"body":{"response":"Lambda was warmed up. V1"},"isBase64Encoded":false}


除了lambda日志外,还将有关呼叫状态的服务信息和JSON格式的响应写入控制台。

像lambda一样,网关API可以在本地运行。
我们执行命令:
sam local start-api

启动时的控制台日志
F:\aws\projects\contact-us-sam-app>sam local start-api
Mounting ContactUsFunction at http://127.0.0.1:3000/contact [POST, OPTIONS]
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. You only need to restart SAM CLI if you update your AWS SAM template
2020-01-06 22:20:30  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)


启动服务器后,我们可以执行请求。我将使用Postman并发送请求以预热lambda。

在控制台中,我们看到
Invoking com.gralll.sam.App::handleRequest (java11)
Fetching lambci/lambda:java11 Docker container image......
Mounting F:\aws\projects\contact-us-sam-app\.aws-sam\build\ContactUsFunction as /var/task:ro,delegated inside runtime container
?[32mSTART RequestId: 27868750-3637-1f80-3d80-53a724da16ef Version: $LATEST?[0m
2020-01-06 19:28:09 27868750-3637-1f80-3d80-53a724da16ef INFO  App - Request was received
2020-01-06 19:28:09 27868750-3637-1f80-3d80-53a724da16ef DEBUG App - {
  "body" : "{\r\n  \"subject\": \"Question\",\r\n  \"question\": \"How much does it cost\",\r\n  \"username\": \"Alex\",\r\n  \"phone\": \"+79999999999\",\r\n  \"email\": \"alex@gmail.com\"\r\n}",
  "resource" : "/contact",
  "requestContext" : {
    "resourceId" : "123456",
    "apiId" : "1234567890",
    "resourcePath" : "/contact",
    "httpMethod" : "POST",
    "requestId" : "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "extendedRequestId" : null,
    "accountId" : "123456789012",
    "identity" : {
      "apiKey" : null,
      "apiKeyId" : null,
      "userArn" : null,
      "cognitoAuthenticationType" : null,
      "caller" : null,
      "userAgent" : "Custom User Agent String",
      "user" : null,
      "cognitoIdentityPoolId" : null,
      "cognitoIdentityId" : null,
      "cognitoAuthenticationProvider" : null,
      "sourceIp" : "127.0.0.1",
      "accountId" : null,
      "accessKey" : null
    },
    "authorizer" : null,
    "stage" : "Prod",
    "path" : "/contact",
    "protocol" : null,
    "requestTime" : null,
    "requestTimeEpoch" : 0,
    "elb" : null
  },
  "multiValueQueryStringParameters" : null,
  "multiValueHeaders" : {
    "Accept" : [ "application/json" ],
    "Accept-Encoding" : [ "gzip, deflate, br" ],
    "Accept-Language" : [ "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7" ],
    "Cache-Control" : [ "no-cache" ],
    "Connection" : [ "keep-alive" ],
    "Content-Length" : [ "150" ],
    "Content-Type" : [ "text/plain;charset=UTF-8" ],
    "Host" : [ "127.0.0.1:3000" ],
    "Origin" : [ "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop" ],
    "Postman-Token" : [ "5cadaccd-6fae-5bc2-b4ef-63900a1725ff" ],
    "Sec-Fetch-Mode" : [ "cors" ],
    "Sec-Fetch-Site" : [ "cross-site" ],
    "User-Agent" : [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" ],
    "X-Forwarded-Port" : [ "3000" ],
    "X-Forwarded-Proto" : [ "http" ],
    "X-Warm-Up" : [ "123" ]
  },
  "pathParameters" : null,
  "httpMethod" : "POST",
  "stageVariables" : null,
  "path" : "/contact",
  "isBase64Encoded" : false,
  "requestSource" : "API_GATEWAY"
}
2020-01-06 19:28:09 27868750-3637-1f80-3d80-53a724da16ef INFO  App - Lambda was warmed up
?[32mEND RequestId: 27868750-3637-1f80-3d80-53a724da16ef?[0m
?[32mREPORT RequestId: 27868750-3637-1f80-3d80-53a724da16ef     Init Duration: 1951.87 ms       Duration: 42.91 ms      Billed Duration: 100 ms Memory Size: 256 MB     Max Memory Used: 102 MB ?[0m
2020-01-06 22:28:11 127.0.0.1 - - [06/Jan/2020 22:28:11] "POST /contact HTTP/1.1" 201 -


当然,日志并不是以最佳方式格式化的。希望将来会解决此问题。

重要提示:更改lambda代码时,无需重新启动API。使用sam build命令重建lambda就足够了
关于错误的一点
Java- aws-serverless-java-container-core, : 502 . :
Invalid API Gateway Response Keys: {'base64Encoded'} in {'statusCode': 200, 'headers': {'Content-Type': 'text/plain'}, 'body': 'Hello World', 'base64Encoded': False} 

- , API Gateway AWS JsonProperty. 'isBase64Encoded' 'base64Encoded', , , . , Java- ContactUsProxyResponse AwsProxyRequest.



3.来自IDEA的本地电话


上面段落中描述的所有内容都是SAM工具的功能。它是从命令行控制的,可以集成到任何界面中。这正是IntelljIDEA AWS Toolkit插件中所做的。

此插件添加了用于直接从IDE启动lambda的其他配置。这是配置窗口的外观。 您必须选择带有lambda描述的模板,或者手动配置设置。 在第一种情况下,将自动从模板中获取用于编译的内存和语言量。在第二种情况下,您可以自己配置RAM的数量,并对限制进行近似计算。 另一个插件使您可以直接从Java代码编辑器或yaml-template的窗口中运行配置。屏幕截图如下:











实际上,仅此而已。通过运行定制的配置,您只需从控制台自动执行频繁的lambda调用即可。同意,很舒服吗?


4.测试


在这里,我们讨论lambda的测试类型。由于我在示例中使用Java,因此测试还将包括用于单元和集成测试的相当标准的工具:Junit 4,Mockito和PowerMockito。

单元测试


要用单元测试覆盖lambda代码,您不需要具有特定的知识。应用标准的Java做法就足够了:锁定类中的所有依赖项并尝试测试请求处理的所有可能情况。

我没有添加所有测试场景,而将自己限制在两个积极和两个消极的场景。

第一个阳性测试验证是否存在X-WARM-UP标头,则DbService和EmailService中没有请求。第二种情况检查如果请求是真实的,则将调用这些服务。这些是最简单的测试,我在其中省略了部分检查。

负方案是在客户端或服务器处理错误的情况下的响应检查。

整合测试


至于集成测试,我决定检查DbService及其与DynamoDB表的配合使用。

在这种情况下,我使用了Localstack工具该解决方案为作为docker容器运行的AWS服务提供了免费的mokas。

要安装此解决方案,只需运行以下命令:
pip install localstack
localstack start

或者,您可以使用docker-compose文件
docker-compose仅引发DynamoDB
version: '2.1'
services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
    image: localstack/localstack
    ports:
      - "4567-4599:4567-4599"
      - "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"
    environment:
      - SERVICES=dynamodb
      - DEBUG=${DEBUG- }
      - DATA_DIR=${DATA_DIR- }
      - PORT_WEB_UI=${PORT_WEB_UI- }
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- }
      - KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }
      - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"


start命令默认引发所有可用的AWS服务。要专门提高DynamoDB,只需设置环境变量:
set SERVICES=dynamodb


Junit 有一个特殊的LocalstackTestRunner,它允许您使用@LocalstackDockerProperties配置启动必要的服务
结果,为DbService编写测试如下所示:
  • 添加测试类。
    @RunWith(LocalstackTestRunner.class)
    @LocalstackDockerProperties(services = { "dynamodb" })
    

  • 建立表格
    爪哇
    @Before
    public void setUp() {
        AmazonDynamoDB clientDynamoDB = TestUtils.getClientDynamoDB();
        dynamoDB = new DynamoDB(clientDynamoDB);
        dbService = new DbService(dynamoDB);
    
        dynamoDB.createTable(
                new CreateTableRequest()
                        .withTableName("ContactUsTable")
                        .withKeySchema(new KeySchemaElement("Id", KeyType.HASH))
                        .withAttributeDefinitions(new AttributeDefinition("Id", ScalarAttributeType.S))
                        .withProvisionedThroughput(new ProvisionedThroughput(10L, 10L)));
    }
                    


  • 我们描述测试场景
    爪哇
    // given
    ContactUsRequest contactUsRequest = new ContactUsRequest("subject", "name", "+79991234545", "123@mail.ru", "Qeustion");
    
    // when
    dbService.putContactUsRequest("123", contactUsRequest);
    
    // then
    Item item = dynamoDB.getTable("ContactUsTable").getItem(new PrimaryKey("Id", "123"));
    assertEquals(contactUsRequest.getSubject(), item.get("Subject"));
    assertEquals(contactUsRequest.getUsername(), item.get("Username"));
    assertEquals(contactUsRequest.getPhone(), item.get("Phone"));
    assertEquals(contactUsRequest.getEmail(), item.get("Email"));
    assertEquals(contactUsRequest.getQuestion(), item.get("Question"));
                  


  • 测试后不要忘记删除表。
    爪哇
    @After
    public void tearDown() {
        dynamoDB.getTable("ContactUsTable").delete();
    }
                   



结果,使用Localstack,我们获得了相当广泛的AWS模拟,可让您模拟这些服务的工作。

端到端测试


要玩E2E场景,最好有机会专门针对运行测试来提高测试AWS服务。这可以使用可选的CloudFormation模板来完成,其中资源将是主模板的副本。

可以通过通过AWS-CLI调用lambda并使用任何可用工具处理结果来完成测试。您仍然可以在单元测试中打电话,但无需创建小怪。

性能测试


由于性能测试值得一本单独的文章甚至一本书,因此我不会尝试将所有信息放在这里。简而言之,在谈到压力测试时,您需要记住,几乎所有的AWS服务都不是免费的,您应该准备提前估算可能的成本。

如果要评估Lambda的必要资源,请使用UI控制台并进行一些测试调用。接下来,使用普通逻辑和数学方法,根据可用资源的数量来评估lambda的性能提高多少。

不要忘记CloudWatch。借助它的帮助,您可以构建具有指示性的仪表板,并基于它们来确定可以负担的lambda参数和支出。


5.无服务器解决方案的成本


解决方案的评估始终是特定的,因为您不仅需要考虑一个呼叫的成本,而且还要考虑传入/传出流量,缓存,日志记录和监视的成本。如果您正在考虑使用lambda,请尝试预测服务将处理的负载。

如果这些是单次调用或每隔几个小时/天运行一次的ETL流程,则lambda更有可能获得回报。如果您预测每秒有几个查询的负载,请确保进行准确的估算。

下面我对lambda和最便宜的EC2服务器的成本进行大概估算,以便您了解有什么问题: lambda的以下参数用于计算:




  • 交货时间: 150毫秒
  • 价格: $ 0.00001667的1GB-s
  • 记忆体: 256 MB

对于EC2 t2.nano:

  • 价格:每月4.75美元
  • 内存: 512 MB
  • vCPU: 1
  • 最大负载:每月5%的CPU

从这里获取 EC2负载数据根据这些计算,指定的服务器可以承受每秒0.3个请求的恒定负载。随着负载的增加,响应时间将增加,这将降低该服务器的效率。

所有这些计算都是非常抽象的,没有考虑很多因素:预付款或大量请求的折扣,lambda执行时间等等。但是他们表明,每秒负载少于1个请求,lambda的成本低于最便宜的EC2服务器。

顺便说一句,如果您需要保留多个应用程序副本或弹性IP,请不要忘记将ALB的价格添加到EC2价格中。


与相同的微服务相比,无服务器解决方案的测试和本地开发不那么受欢迎。但是,越来越多的人研究和应用这些技术,并为各种开源产品提供了变得更好,更高效的机会。这样的解决方案极大地简化了需要尽快发布产品而不必配置整个基础架构的公司的生命。但是,即使在已经开发的产品中,我认为也存在无服务器数据库或lambda的地方。

我并没有声称自己是无服务器解决方案测试领域的专家,但是,根据我个人的积极经验,我决定重点介绍本文的要点。我希望它们对某人有用,也许你们中的一些人可以补充甚至纠正我,对此我将非常高兴。


有用的链接



All Articles