Lambda能挂在ALB后面,当作ALB的target group
, Lambda返回HTTP响应给ALB:
本节我们将创建一个Lambda和ALB,并将Lambda绑在ALB上面进行测试
进入Lambda页面,创建新的函数。命名为lambda-alb
, 运行环境选择Python 3.7
:
其他选项保持默认,进行创建。
进入EC2的Load Balancer页面,创建ALB:
为ALB命名为alb-for-lambda
:
VPC保持默认,选择两个或多个子网:
创建新的安全组,在安全组里将放行80和443端口的流量:
在新的页面里,输入安全组的名称:
放通80和443端口:
创建完成后,回到ALB页面,刷新安全组,使用刚才创建的安全组。
在target group选项,选择创建新的target group:
在新的页面,选择使用Lambda Function
:
为target group命名,例如lambda-target-group
,然后进入下一步:
选择使用上一步创建的lambda:
点击创建,状态变为Active
时,可以进行访问
在浏览器访问上一步创建ALB的url。
它会下载为download
文件,里面是lambda的返回结果:
下载成文件,这显然不符合预期
需要使用专用的返回格式(参考: https://docs.aws.amazon.com/lambda/latest/dg/services-alb.html ):
{
"statusCode": 200,
"statusDescription": "200 OK",
"isBase64Encoded": False,
"headers": {
"Content-Type": "text/html"
},
"body": "<h1>Hello from Lambda!</h1>"
}
修改Lambda代码,并进行部署:
重新访问ALB地址:
用户在访问ALB URL时,可能会携带一些参数,例如query string
, post body
, user-agent
等,这些都可以由ALB传给Lambda的event
参数:
修改Lambda代码为:
import json
def lambda_handler(event, context):
# TODO implement
return {
"statusCode": 200,
"statusDescription": "200 OK",
"isBase64Encoded": False,
"headers": {
"Content-Type": "application/json"
},
"body": json.dumps(event) # 将event返回给ALB
}
访问ALB地址,并加入一些测试的query string
,可以看到ALB传给Lambda的event
具体内容:
具体的字段说明如下:
ALB支持Multi-header
传值,当在浏览器对于同一个参数传入多个值时,ALB传给Lambda时会将其转换为数组:
默认Multi-value header在target group中是关闭的,需要单独开启:
为了让target group能够访问Lambda,Lambda必须要给我们创建的target group授权才能进行调用。
其实这一步已经帮我们自动实现,在target group创建时,会在Lambda中同时创建一条Resource-based policy
。
我们可以进入Lambda的Configuration => Permission
页面进行确认:
下拉后会发现Lambda有一条Resource-based policy
:
在这条policy里,声明了Lambda允许对应的target group来调用它:
参考: https://docs.aws.amazon.com/lambda/latest/dg/services-alb.html