乐趣区

关于amazon:利用-Amazon-API-Gateway-和-Amazon-Lambda-处理-Cloudfront-的内容请求

概述

国内 Amazon Cloudfront 目前不反对 Lambda@edge 性能,不能实现基于 CDN 的 A/B 测试、rewrite、redirect、token 认证和产生 response 等性能,本文介绍如何利用 API Gateway 和 Lambda 实现 Lambda@edge 的性能。上面试验介绍通过 request header 参数值,实现 redirect 和 rewrite 的测试场景,依据 header(test_version)参数值,回源到指定目录的文件,依据 header(redirect)参数值,返回 302 重定向地址。

亚马逊云科技开发者社区为开发者们提供寰球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、流动与比赛等。帮忙中国开发者对接世界最前沿技术,观点,和我的项目,并将中国优良开发者或技术举荐给寰球云社区。如果你还没有关注 / 珍藏,看到这里请肯定不要匆匆划过,点这里让它成为你的技术宝库!

整体试验的架构图如下:

架构图阐明:

  1. Cloudfront 是 Amazon 的 CDN 服务,能够设置源站域名,回源 header,缓存策略等。
  2. API Gateway 有两种类型能够反对 rewrite 和 redirect 测试场景,试验中采纳 HTTP API,思考到老本更低,同时不须要 Rest API 的高级性能。
  3. Lambda 实现了 rewrite 和 redirect 的测试代码,反对验证 security header。反对多种支流语言,试验中采纳 Python3.9 语言实现。
  4. S3 保留测试的 html 和 png 文件。

具体步骤阐明

1. 新建 S3 Bucket

比方:bucket name:lambda-api-2022

上传文件列表:

index.html – 欢送页

v1/test.html – A 测试页

v1/test.png – A 测试图片

v2/test.html – B 测试页

v2/test.png – B 测试图片

2. 新建 Lambda 程序

1)新建 IAM Role,执行 Lambda 程序,比方 Role name:RoleForLambda
须要的权限如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "s3get",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::lambda-api-2022/*"
        },
        {
            "Sid": "putlogs",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

2)创立 Lambda 程序
采纳下列的参数和配置:

Function name:lambdaapi

Runtime:Python 3.9

Execution role:RoleForLambda(上一步创立的)

批改 Configuration 的配置:

增加 Environment variables

增加 Key=bucket,Value=lambda-api-2022

增加 Key=lambda_auth,Value=lambdaapi_test

增加 Key=redirect_path,Value=https://xxx.cloudfront.net,value 来自上面创立的 Cloudfront distribution

General configuration

批改 Timeout 为 20 秒

Lambda Source Code:

import boto3
import base64
import os

s3_client = boto3.client('s3')

def lambda_handler(event, context):

    print(event)

    # check security header
    if 'lambda_auth' in event['headers'] and event['headers']['lambda_auth'] == os.environ['lambda_auth']:

        bucket = os.environ['bucket']
        
        key = event['rawPath'][1:]  # request URI
    
        print(key)
        
        if len(key) == 0:
            key = 'index.html'
        
        # rewrite url
        if 'test_version' in event['headers']:
            key = event['headers']['test_version']+'/'+key
        
        # redirect    
        if 'redirect' in event['headers'] and event['headers']['redirect'] == 'true':
            return {
                'statusCode': 302,
                'statusDescription': 'Found',
                'headers': {'Location': os.environ['redirect_path'] + '/' + key }
            }
        
        # return content body - rewrite
        try:
            response = s3_client.get_object(Bucket = bucket, Key = key)
            responseBody = response['Body'].read() # return bytes from S3
            responseContentType = response['ResponseMetadata']['HTTPHeaders']['content-type']
            return {'headers': { "Content-Type": responseContentType},
                    'statusCode': 200,
                    'body': base64.b64encode(responseBody).decode('utf-8'),
                    'isBase64Encoded': True
                }
        except Exception as e:
            print('error message -', e.__class__.__name__, ':', e)
            
            return {
                    'statusCode': 200,
                    'body': 'no file:'+key
                }
    
    else:
        # auth failed
        return {
                'statusCode': 403,
                'body': 'request is forbidden'
            }

Lambda Source Code 阐明:

在 Cloudfront 回源时,增加 lambda_auth header,用于 Lambda 认证申请,当认证失败时,返回 403 谬误。

当申请根目录时,返回 index.html

当 request header 蕴含 test_version 时,转向到指定目录下的文件。

将返回的 body 通过 base64 编码,以反对 binary 对象。

当 request header 蕴含 redirect=true 时,返回 302 重定向信息。

3. 新建 API Gateway

在 API Gateway 中,新建 HTTP API,比方 API Name:lambdaapi

新建 Lambda integration,抉择上一步创立的 Lambda(lambdaapi)

在 Configure routes 时,Resource path 设置为“/{proxy+}”

在 Deploy Stages 中,找到 $default stage 的 Invoke URL,如 https://xxx.execute-api.xxx.amazonaws.com,此为 API Gateway 的申请地址。

测试 API gateway:

  • 测试 security header

测试命令:curl https://xxx.execute-api.xxx.amazonaws.com?trk=cndc-detail

返回后果:request is forbidden

  • 测试拜访根门路,传入 lambda_auth header

测试命令:curl -v -H“lambda_auth:lambdaapi_test”https://xxx.execute-api.xxx.amazonaws.com?trk=cndc-detail

返回后果:statusCode=200

  • 拜访 B 测试页,传入 lambda_auth header 和 test_version header

测试命令:curl -H“lambda_auth:lambdaapi_test”-H“test_version:v2”https://xxx.execute-api.xxx.amazonaws.com/test.html?trk=cndc-…

返回 v2/test.html 的内容

  • 拜访 B 测试图片,传入 lambda_auth header 和 test_version header

测试命令:curl -H“lambda_auth:lambdaapi_test”-H“test_version:v2”https://xxx.execute-api.xxx.amazonaws.com/test.png?trk=cndc-d… > test.png

将 response 保留为 test.png 图片。

  • 测试 redirect,传入 redirect header

测试命令:curl -v -H“lambda_auth:lambdaapi_test”-H“test_version:v1”-H“redirect:true”https://xxx.execute-api.xxx.amazonaws.com/test.html

返回 302 重定向信息

4. 配置 Cloudfront

1)创立 Origin request policy,Amazon Cloud Global 反对该性能

在 Cloudfront Policies 中,新建 origin request policy,例如 Name:lambdaapi

配置如下:

Headers:抉择 Include the following headers,并手工增加 header:test_version 和 redirect

Query strings: All

2)创立 Cloudfront Distribution

在 Cloudfront 中,新建 Distribution,例如 Description:lambdaapi

配置如下:

Origin domain:xxx.execute-api.xxx.amazonaws.com,下面创立的 HTTP API 域名

Protocol:HTTPS only

Add custom header:

Header name = lambda_auth,Value = lambdaapi_test

在 Amazon Cloud Global,反对 Cache policy and origin request policy (recommended),配置上面两个参数:

Cache policy:CachingDisabled

Origin request policy:Custom lambdaapi

或者在 Amazon Cloud China,反对 Legacy cache settings,配置上面 3 个参数:

Headers:抉择 Include the following headers,并手工增加 header:test_version 和 redirect。

Query strings: All

Cookies:All

如果不须要 Cloudfront 缓存内容时,须要设置 Object caching 为 Customize,同时将 Minimum TTL、Maximum TTL 和 Default TTL 都设为 0.

注:需新建 origin 和 behavior,配合 redirect 后 Cloudfront 地址。

5. 测试 Cloudfront

1. 在 Cloudfront Distributions(Lambdaapi)的 General Details 中,找到 Distribution domain name,例如 cloudfront.net

2. 拜访 A 测试页,传入 test_version header

测试命令:curl -H“test_version:v1”https://xxx.cloudfront.net/test.html?trk=cndc-detail

返回 v1/test.html 的内容

3. 测试 redirect,传入 test_version 和 redirect header

测试命令:curl -I -H“test_version:v1”-H“redirect:true”https://xxx.cloudfront.net/test.html?trk=cndc-detail

返回 302 重定向的内容

论断

在这篇文章中,介绍了如何利用 API Gateway 和 Lambda 解决 Cloudfront 的内容申请,实现 Lambda@edge 的性能,在试验中,介绍了 Amazon S3、Lambda、API Gateway 和 Cloudfront 的配置办法,实现了 rewrite 和 redirect 的测试场景。

参考资料

  • https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStar…
  • https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_cre…
  • https://docs.aws.amazon.com/lambda/latest/dg/getting-started….
  • https://docs.aws.amazon.com/apigateway/latest/developerguide/…
  • https://docs.aws.amazon.com/AmazonCloudFront/latest/Developer…
  • https://docs.aws.amazon.com/AmazonCloudFront/latest/Developer…

本篇作者

薛召兵
Amazon 解决方案架构师,负责帮忙客户进行上云架构的设计和征询。同时致力于 Amazon 容器服务、媒体服务和机器学习服务在国内和寰球商业客户的利用和推广,推动企业服务迁徙上云过程。有 10 年以上的软件开发、售前技术支持、零碎架构设计等教训。

文章起源:https://dev.amazoncloud.cn/column/article/6309c985d4155422a46…

退出移动版