AWS Application Load Balancer 대상에 Lambda(Python)를 지정해 보았습니다.
12829 단어 람다ALBserverlessAWS
애플리케이션 로드 밸런서(ALB) 대상에 대해 AWS Lambda를 선택할 수 있습니다.
지금까지 Lambda를 외부에서 호출하는 경우 API Gateway에서 일반이라고 생각하지만 ALB에서 호출 할 수 있습니다.
API Gateway를 사용하여 구현하는 경우 URL 전환하려는 웹 앱을 구현하기가 어려웠다고 생각합니다. 하지만 ALB를 통해 Lambda를 실행할 수 있게 되면 URL 전환의 앱 구현도 간단해진다고 생각합니다.
이미 사용할 수 있게 되었으므로 시도해 보았습니다.
우선은 파라미터 조사용 Lambda 함수를 준비했습니다
어떤 매개변수가 Lambda 함수에 전달되는지 조사하려면 Cloudwatch logs에서 확인합니다. 블로그에 쓰여진 소스를 참고로 다음과 같이 했습니다.
lambda_function.py
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
def lambda_handler(event, context):
logger.debug( event )
response = {
"statusCode": 200,
"isBase64Encoded": False,
"headers": {
"Content-Type": "text/html; charset=utf-8"
}
}
response['body'] = """<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>"""
return response
ALB를 만들었습니다.
Lambda 함수를 만든 후 ALB를 설정했습니다.
대상 그룹 만들기 화면에서 이전에는 없었던 Lambda 함수를 지정할 수 있습니다. 이제 방금 만든 Lambda 함수를 선택합니다.
타겟 그룹 이외는 지금까지의 ALB 작성과 다르지 않았다고 생각합니다.
ALB에 액세스하려고했습니다.
ALB 작성 후,
curl http://***.ap-northeast-1.elb.amazonaws.com/lambdatest/?a=b&c=d
로 액세스해, Cloudwatch logs에 출력되고 있는 event 파라미터를 조사해 보았더니, 이하의 출력이 되어 있었습니다 (일부 마스크하고 있습니다).curl의 출력은 HTML이 출력되었습니다.
{'requestContext':
{'elb': {
'targetGroupArn': 'arn:aws:elasticloadbalancing:ap-northeast-1:***:targetgroup/TestLoggingLambda/***'
}
},
'httpMethod': 'GET',
'path': '/lambdatest/',
'queryStringParameters': {'a': 'b', 'c': 'd'},
'headers': {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'accept-encoding': 'gzip, deflate',
'accept-language': 'ja,en-US;q=0.9,en;q=0.8,th;q=0.7',
'connection': 'keep-alive',
'host': '***.ap-northeast-1.elb.amazonaws.com',
'upgrade-insecure-requests': '1',
'user-agent': '***',
'x-amzn-trace-id': '***'',
'x-forwarded-for': '***'',
'x-forwarded-port': '80',
'x-forwarded-proto': 'http'
},
'body': '',
'isBase64Encoded': False
}
GET 파라미터는,
queryStringParameters
에 격납되는 것 같습니다. 요청 헤더도 가져왔습니다.POST로 액세스하려고했습니다.
curl -F "hoge=fuga" -F "form2=テスト" http://***.ap-northeast-1.elb.amazonaws.com/lambdatest/
에서 액세스 해 보았을 때, body 부분에 base64encode 된 상태로 데이터가 포함되어있는 것 같습니다.{'requestContext':
{'elb': {
'targetGroupArn': 'arn:aws:elasticloadbalancing:ap-northeast-1:***:targetgroup/TestLoggingLambda/***'
}
},
'httpMethod': 'POST',
'path': '/lambdatest/',
'queryStringParameters': {},
'headers': {
'accept': '*/*',
'content-length': '246',
'content-type': 'multipart/form-data; boundary=------------------------66c2ae32e35a634a',
'expect': '100-continue',
'host': '***.ap-northeast-1.elb.amazonaws.com',
'user-agent': ''***'',',
'x-amzn-trace-id': ''***'',',
'x-forwarded-for': ''***'',',
'x-forwarded-port': '80',
'x-forwarded-proto': 'http'
},
'body':'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS02NmMyYWUzMmUzNWE2MzRhDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImhvZ2UiDQoNCmZ1Z2ENCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tNjZjMmFlMzJlMzVhNjM0YQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmb3JtMiINCg0K44OG44K544OIDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTY2YzJhZTMyZTM1YTYzNGEtLQ0K',
'isBase64Encoded': True
}
GET 및 POST에서 매개변수를 얻는 샘플
Lambda 함수에 건너오는 파라미터를 알았으므로 GET과 POST의 경우 샘플 프로그램을 작성해 보았습니다. POST 데이터의 디코딩이 번거롭기 때문에 Python의 cgi 모듈을 사용하고 있습니다.
lambda_function.py
import base64
import io
import cgi
def lambda_handler(event, context):
response = {
"statusCode": 200,
"isBase64Encoded": False,
"headers": {
"Content-Type": "text/html; charset=utf-8"
}
}
response['body'] = """<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<p>Hello World!</p>"""
if event['httpMethod'] == "GET":
for k,v in event['queryStringParameters'].items():
response['body'] += "<p>" + k + " : " + v + "</p>"
elif event['httpMethod'] == "POST":
fp = io.BytesIO(base64.b64decode(event['body']))
environ = {'REQUEST_METHOD': 'POST'}
headers = {
'content-type': event['headers']['content-type'],
'content-length': event['headers']['content-length']
}
form = cgi.FieldStorage(fp=fp, environ=environ, headers=headers)
for f in form.list:
response['body'] += "<p>" + f.name + " : " + f.value + "</p>"
response['body'] += """<p>ALBからLambdaを呼び出しています</p>
</body>
</html>"""
return response
참고로 기사 : [Python] POST 된 multipart / form-data를 FieldStorage로 구문 분석
구성을 생각해 보면
지금까지의 결과, GET이나 POST로 교환하는 페이지는 작성할 수 있을 것 같습니다. 이를 바탕으로 구성을 생각해 보면 정적 페이지는 CloudFront+S3에서 표시를 시켜 동적 처리가 필요한 페이지만 CloudFront+ALB+Lambda+(다음은 필요한 서비스)로 하면 EC2를 이용하지 않아도 대부분의 사이트는 작성할 수 있는 것 같았습니다. 그림으로 보면, 이런 느낌입니다.
EC2가 없어지는 것으로 운용 부하가 격감한다고 생각합니다.
Lambda의 런타임에 Ruby나 PHP도 지정할 수 있게 되었기 때문에, 지금까지 EC2상에서 실행하고 있던 간단한 프로그램은, Lambda로 이행할 수 있을지도 모릅니다.
운용으로 편하게 하고 싶기 때문에, 블로그를 보고, 서둘러 테스트한 결과였습니다.
Reference
이 문제에 관하여(AWS Application Load Balancer 대상에 Lambda(Python)를 지정해 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/izanari/items/df5780d5444acee981c4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)