AWS lambda

1. 简介

https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html

AWS lambda可以在无需管理服务器以及计算资源的情况下运行代码,典型的无服务架构。同时提供了动态伸缩、高可用的计算资源。无服务的一大好处是计算资源完全托管,无需用户管理,只需要按调用次数付费即可。用户可以更加专注于自己的代码。

AWS lambda可作为AWS服务之间的关联方式,使用lambda作为AWS服务之间交互,定义交互的代码逻辑。

1. 部署方式

  • 压缩源代码文件zip,包含所有源代码以及依赖。lambda支持多种主流语言的运行时。
  • 容器镜像,如docker image等符合OCI标准的镜像。image会被存储到Amazon ECR

2. 配置方式

  • 浏览器的Lambda console
  • AWS CLI
  • AWS SDK or CDK

example:

1
2
3
4
5
6
7
8
9
10
# lambda function
import json

def lambda_handler(event, context):
print(event)
print(context)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Test Event Name
test

Response
{
"statusCode": 200,
"body": "\"Hello from Lambda!\""
}

Function Logs
START RequestId: 2d074e33-51bf-4176-8d08-782700ffae62 Version: $LATEST
{'hello': 'hello', 'name': 'jack', 'other': 'rose'}
LambdaContext([aws_request_id=2d074e33-51bf-4176-8d08-782700ffae62,log_group_name=/aws/lambda/test_lambda,log_stream_name=2022/06/14/[$LATEST]f5bfdd9530b44cd091ed19ac7b172ab4,function_name=test_lambda,memory_limit_in_mb=128,function_version=$LATEST,invoked_function_arn=arn:aws:lambda:us-west-2:061479767641:function:test_lambda,client_context=None,identity=CognitoIdentity([cognito_identity_id=None,cognito_identity_pool_id=None])])
END RequestId: 2d074e33-51bf-4176-8d08-782700ffae62
REPORT RequestId: 2d074e33-51bf-4176-8d08-782700ffae62 Duration: 0.93 ms Billed Duration: 1 ms Memory Size: 128 MB Max Memory Used: 35 MB

Request ID
2d074e33-51bf-4176-8d08-782700ffae62

2. 概念

以s3和aws lambda交互为例

1. function

lambda函数的处理逻辑。event可以手动传入invoke或者是由其他的AWS服务发送给lambda函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import json
import urllib.parse
import boto3

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
#print("Received event: " + json.dumps(event, indent=2))

# Get the object from the event and show its content type
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
try:
response = s3.get_object(Bucket=bucket, Key=key)
print("CONTENT TYPE: " + response['ContentType'])
return response['ContentType']
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
raise e

返回值

https://docs.aws.amazon.com/lambda/latest/dg/python-handler.html

function返回值的处理,取决于lambda的调用类型以及触发lambda服务的类型。

2. trigger

lambda函数的触发器,可以是被某些AWS服务所触发。如由s3 bucket对象创建触发:

⚠️ lambda函数如果被s3触发后,行为是写入同一个s3中,可能回导致递归的函数触发,造成严重的结果。

image-20220614155236190

触发方式

1. 同步触发 synchronous invocation

触发lambda函数并等待其返回结果。

1
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{ "key": "value" }' response.json

查询lambda函数的log

1
aws lambda invoke --function-name my-function out --log-type Tail --query 'LogResult' --output text |  base64 -d

2. 异步触发 asynchronous invocation

Lambda将event放置到队列中并立刻返回成功消息。一个额外的进程会读取队列中的event并发送给lambda函数执行。

1
2
3
aws lambda invoke --function-name my-function  --invocation-type Event --cli-binary-format raw-in-base64-out --payload '{ "key": "value" }' response.json

# --invocation-type Event 异步触发

3. event

传递给function的参数,形式是一个json字典(手动触发时,event可以是任何的数据结构)。由AWS service触发时,event的的格式基本为json,具体参数取决于service类型。

不同的AWS service的event json格式各不相同,如s3触发的json格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "1970-01-01T00:00:00.000Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "EXAMPLE"
},
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"responseElements": {
"x-amz-request-id": "EXAMPLE123456789",
"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "testConfigRule",
"bucket": {
"name": "my-test-bucket",
"ownerIdentity": {
"principalId": "EXAMPLE"
},
"arn": "arn:aws:s3:::example-bucket"
},
"object": {
"key": "content",
"size": 1024,
"eTag": "0123456789abcdef0123456789abcdef",
"sequencer": "0A1B2C3D4E5F678901"
}
}
}
]
}

bucket不存在时,使用上述event触发lambda的response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Test Event Name
test

Response
{
"errorMessage": "An error occurred (AccessDenied) when calling the GetObject operation: Access Denied",
"errorType": "ClientError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 23, in lambda_handler\n raise e\n",
" File \"/var/task/lambda_function.py\", line 17, in lambda_handler\n response = s3.get_object(Bucket=bucket, Key=key)\n",
" File \"/var/runtime/botocore/client.py\", line 391, in _api_call\n return self._make_api_call(operation_name, kwargs)\n",
" File \"/var/runtime/botocore/client.py\", line 719, in _make_api_call\n raise error_class(parsed_response, operation_name)\n"
]
}

Function Logs
START RequestId: d2b2a1b0-db50-49d4-acf8-41e58ce880c3 Version: $LATEST
An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
Error getting object content from bucket my-test-bucket. Make sure they exist and your bucket is in the same region as this function.
[ERROR] ClientError: An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 23, in lambda_handler
    raise e
  File "/var/task/lambda_function.py", line 17, in lambda_handler
    response = s3.get_object(Bucket=bucket, Key=key)
  File "/var/runtime/botocore/client.py", line 391, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 719, in _make_api_call
    raise error_class(parsed_response, operation_name)
END RequestId: d2b2a1b0-db50-49d4-acf8-41e58ce880c3
REPORT RequestId: d2b2a1b0-db50-49d4-acf8-41e58ce880c3 Duration: 966.62 ms Billed Duration: 967 ms Memory Size: 128 MB Max Memory Used: 71 MB Init Duration: 452.77 ms

Request ID
d2b2a1b0-db50-49d4-acf8-41e58ce880c3

3. 权限配置

执行角色 execution role:可以为lambda函数配置execution role。使用execution role可以在lambda函数内部访问该role可以访问到的aws资源。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!