侧边栏壁纸
博主头像
霍義博主等级

只要学不死,就往死里学!

  • 累计撰写 10 篇文章
  • 累计创建 9 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

静态文件上传AWS-S3并实时调用阿里云-CDN自动刷新缓存预热

霍義
2024-10-09 / 0 评论 / 0 点赞 / 19 阅读 / 12260 字 / 正在检测是否收录...


静态文件上传AWS-S3并实时调用阿里云-CDN自动刷新缓存预热

1.需求

2.部署操作

2.1 设置S3事件通知

2.2 创建Lambda函数生成预签名URL并调用阿里云SDK刷新预热

2.2.1 具体设置

2.2.2 导入第三方依赖至Lambda

2.2.2.1 下载依赖

2.2.2.2 上传依赖

2.3 创建SNS主题来发送通知

2.3.1 邮箱通知

2.3.2 TG通知

2.3.2.1 获取 Telegram Bot Token 和 Chat ID

2.3.2.2 创建 AWS Lambda 函数

2.3.2.3 通过 AWS SNS 触发 Lambda 来发送消息

2.4 测试完整流程

1.需求

#需求
后端程序上传静态文件至S3存储桶的内容,实时发送对应的URL给阿里云CDN,并自动加载缓存预热.

2.部署操作

2.1 设置S3事件通知

1.登录 AWS 管理控制台,进入 S3 控制台.
2.选择存储桶:选择你要监控的存储桶.
3.配置事件通知:
  • 点击"Properties"(属性).
  • 向下滚动,找到"Event Notifications"(事件通知),点击"Create Event Notification"(创建事件通知).
  • 为通知命名,例如"NewFileUpload".
  • 选择"All object create events"(所有对象创建事件),确保选择了正确的文件夹或存储桶根目录.
  • 在Destination中,选择"Lambda Function"(Lambda 函数)作为目标.暂时可以不用选择具体Lambda函数,我们后面会创建一个Lambda函数.

2.2 创建Lambda函数生成预签名URL并调用阿里云SDK刷新预热

2.2.1 具体设置

1.进入 Lambda 控制台:
  • 在 AWS 管理控制台中,打开 Lambda 控制台.
  • 点击 Create function(创建函数).
2.选择创建方式:
  • 选择 Author from scratch(从头创建).
  • 输入函数名称(例如 "GenerateS3SignedUrl").
  • 运行时选择 Python 3.9/3.10/3.12.
  • 设置执行角色为 Create a new role with basic Lambda permissions(使用基本权限创建新角色).
3.编辑 Lambda 代码:
  • 在 Lambda 函数的编辑页面中,替换代码为以下内容(该代码生成预签名 URL 并发送 SNS 通知):
#代码
import json
import boto3
from urllib.parse import unquote_plus
import os
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException, ServerException
from aliyunsdkcore.auth.credentials import AccessKeyCredential
from aliyunsdkcdn.request.v20180510.PushObjectCacheRequest import PushObjectCacheRequest
​
# 创建 AWS 客户端
s3_client = boto3.client('s3')
sns_client = boto3.client('sns')
​
# 全局变量用于计数已刷新文件数
files_refreshed = 0
​
# 阿里云 CDN 客户端设置
def push_to_aliyun_cdn(file_url):
    credentials = AccessKeyCredential(os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'], os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'])
    client = AcsClient(region_id='cn-hongkong', credential=credentials)
​
    request = PushObjectCacheRequest()
    request.set_accept_format('json')
    request.set_Area("overseas")
    #request.set_L2Preload(False)
    request.set_ObjectPath(file_url)  # 这里将 S3 文件的 URL 设置为 CDN 推送对象
​
    response = client.do_action_with_exception(request)
    return str(response, encoding='utf-8')
​
def lambda_handler(event, context):
    global files_refreshed  # 引入全局变量计数
​
    # 获取上传文件的信息
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    file_key = unquote_plus(event['Records'][0]['s3']['object']['key'])
    
    # 构建 S3 对象的公共 URL
    region = 'ap-southeast-1'  # 替换为你的 S3 存储桶所在的区域
    #url = f"https://{bucket_name}.s3.{region}.amazonaws.com/{file_key}"
    url = f"http://aws-s3.demo.com/{file_key}"    # 替换为你阿里云绑定的CDN加速域名
    
    # 推送到阿里云 CDN
    try:
        cdn_response = push_to_aliyun_cdn(url)
        print(f"CDN response: {cdn_response}")
        files_refreshed += 1  # 成功推送后,计数器加 1
    except (ClientException, ServerException) as e:
        print(f"CDN push error: {str(e)}")
    
    # 发送 SNS 通知,包含已刷新数量信息
    sns_topic_arn = 'arn:aws:sns:ap-southeast-1:23325113821:s3_sns_01'  # 替换为你的 SNS 主题 ARN
    message = (f"New file uploaded and refreshed on CDN: {url}\n"
               f"Total files refreshed: {files_refreshed}")
    
    sns_client.publish(
        TopicArn=sns_topic_arn,
        Message=message,
        Subject="S3 File Upload and CDN Refresh Notification"
    )
​
    return {
        'statusCode': 200,
        'body': json.dumps(f"URL: {url}")
    }
4.为 Lambda 函数添加 S3 访问权限:
  • 点击 Lambda 函数的 "Configuration"(配置),然后选择 "Permissions"(权限).
  • 点击执行角色的名称,进入 IAM 控制台.
  • 在 IAM 控制台中,选择 "Attach policies"(附加策略).
  • 搜索并选择 "AmazonS3ReadOnlyAccess" 和 "AmazonSNSFullAccess",点击 "Attach policy"(附加策略).
5.配置 S3 事件通知与 Lambda 函数:
  • 回到 S3 控制台,重新进入之前的事件通知配置.
  • 在 Destination 部分,选择刚才创建的 Lambda 函数("GenerateS3SignedUrl").
  • 保存事件通知.
#阿里云AK/SK添加环境变量
Lamdba函数 --> 项目名称 --> 配置 --> 环境变量 --> 编辑
#例子
ALIBABA_CLOUD_ACCESS_KEY_ID         LTAI5**************
ALIBABA_CLOUD_ACCESS_KEY_SECRET     07j69**************

2.2.3 导入第三方依赖至Lambda

2.2.3.1 下载依赖

#requests
mkdir python
pip3.10 install requests -t python/
zip -r9 requests-layer.zip python/
#aliyun-python-sdk-core
mkdir python
pip3.10 install cryptography==3.3.2 install aliyun-python-sdk-cdn==3.7.1 -t  python/
zip -r9 aliyun-python-sdk-core.zip python/
#alibaba-cdn
mkdir python
pip3.10 install alibabacloud_cdn20180510==4.0.0 -t python/
zip -r9 alibaba-cdn.zip python/

2.2.3.2 上传依赖

1.上传层到 Lambda:
  • 登录 AWS 管理控制台.
  • 转到 Lambda 页面,点击 "Layers".
  • 选择 "Create Layer",上传你刚刚创建的 ZIP 文件,并选择与 Lambda 函数相同的 Python 运行时.
2.将层与 Lambda 函数关联:
  • 打开你的 Lambda 函数,在 "Layers"部分,选择 "Add a layer".
  • 选择你刚刚创建的层并将其添加到 Lambda 函数中.

2.3 创建SNS主题来发送通知

1.进入 SNS 控制台:
  • 在 AWS 管理控制台中,打开 SNS 控制台.
2.创建 SNS 主题:
  • 点击 Create topic(创建主题).
  • 选择 Standard 类型,输入主题名称(例如 "S3FileUploadNotification"),然后点击 Create topic.

2.3.1 邮箱通知

1.订阅 SNS 主题:
  • 在创建好的 SNS 主题中,点击 Create subscription(创建订阅).
  • 在 Protocol(协议) 中选择 Email(你也可以选择 SMS、HTTP 等).
  • 在 Endpoint(端点) 中,输入接收通知的邮箱地址.
  • 点击 Create subscription.
2.确认订阅:
  • 收到一封 SNS 邮件,在邮件中点击确认链接,订阅生效.

2.3.2 TG通知

2.3.2.1 获取 Telegram Bot Token 和 Chat ID

1创建 Telegram Bot
  • 打开 Telegram 应用,搜索并启动 BotFather.
  • 发送 /start,然后输入 /newbot 来创建一个新的 bot.
  • 按照提示给你的 bot 取个名字,并设置一个唯一的用户名(必须以 bot 结尾).
  • 创建完成后,BotFather 会提供一个 Bot Token.记下这个 Token,稍后会用到.
2 获取 Chat ID
  • 打开 Telegram 应用,搜索并启动刚创建的 bot,点击 "Start".
  • 创建群组邀请Bot进入群组,并@发送/Start消息到 bot.
  • 在浏览器中访问以下 URL(替换 YOUR_BOT_TOKEN 为刚刚获得的 Token):
      https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates
  • 查找返回的 JSON 数据,找到你的 chat.id.该 chat.id 将用于向你的 Telegram 用户或群组发送消息.

2.3.2.2 创建 AWS Lambda 函数

1.创建 Lambda 函数
  • 登录到 AWS 管理控制台,进入 Lambda 控制台.
  • 点击 Create function(创建函数),选择 Author from scratch.
  • 给你的函数命名,例如 SendToTelegram.
  • 选择运行时环境为 Python 3.x.
  • 创建完成后,进入函数编辑页面.
#代码
import json
import requests
​
TELEGRAM_BOT_TOKEN = '5162718492:AAG*****************T0'      #Bot_Token内容
CHAT_ID = '-5142513213'     #群组ID,一般群组ID都会为负数(-5142513213)
​
def lambda_handler(event, context):
    message = event['Records'][0]['Sns']['Message']
    
    # 发送消息到 Telegram
    url = f'https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage'
    payload = {
        'chat_id': CHAT_ID,
        'text': message,
        'disable_web_page_preview': True  # 禁用缩略图和网页预览
    }
    
    response = requests.post(url, json=payload)
    
    # 打印响应结果到日志中
    print(f"Response: {response.status_code}, {response.text}")
    
    return {
        'statusCode': response.status_code,
        'body': json.dumps('Message sent to Telegram!')
    }
3.配置 Lambda 执行角色
  • 给 Lambda 函数分配合适的权限:
  • 进入 Configuration -> Permissions.
  • 点击执行角色,附加 AWSLambdaBasicExecutionRole,AmazonSNSFullAccess策略.

2.3.2.3 通过 AWS SNS 触发 Lambda 来发送消息

1.创建 SNS 主题
  • 进入 SNS 控制台.
  • 点击 Create topic,选择 Standard 类型,命名你的主题.
  • 主题创建后,点击 Create subscription.
  • 在 Protocol 中选择 AWS Lambda,在 Endpoint 中选择刚才创建的 Lambda 函数 SendToTelegram.
  • 创建订阅后,当 SNS 主题收到消息时,它将触发 Lambda 函数发送消息到 Telegram.
2.发送测试消息
  • 在 SNS 控制台中,进入你创建的 SNS 主题.
  • 点击 Publish message.
  • 输入消息内容,然后点击 Publish.
  • 你应该会在 Telegram 上收到一条消息.

2.4 测试完整流程

1.上传文件到 S3 存储桶:
  • 打开 S3 控制台,选择之前配置事件通知的存储桶.
  • 点击 Upload,上传任意文件.
2.检查 Lambda 执行情况:
  • 在 Lambda 控制台中,查看 Monitor(监控) 选项卡,确保 Lambda 函数已成功执行.
3.接收信息
  • 上传文件后,你应该会在订阅的邮箱/Telegram中收到包含文件预签名 URL 的通知.
  • 通过该 URL,你可以访问 S3 中刚上传的文件.

0

评论区