如何避免AWS Lambda并发创建同一CloudFront对象的无效请求?
解决CloudFront并发无效请求问题
要避免针对同一对象重复创建InProgress状态的CloudFront缓存无效请求,核心是在创建新请求前先检查当前是否存在符合条件的正在进行的无效请求。以下是修改后的代码及关键说明:
修改后的代码
from __future__ import print_function import boto3 import time from botocore.config import Config config = Config( retries={ 'max_attempts': 6, 'mode': 'standard' } ) cloudfront = boto3.client('cloudfront', config=config) DISTRIBUTION_ID = 'xxxxx' # 替换为你的CloudFront分发ID def has_in_progress_invalidation(target_path): """检查指定分发下是否存在包含目标路径的InProgress状态无效请求""" marker = None while True: # 获取无效请求列表,处理分页逻辑 if marker: response = cloudfront.list_invalidations(DistributionId=DISTRIBUTION_ID, Marker=marker) else: response = cloudfront.list_invalidations(DistributionId=DISTRIBUTION_ID) for invalidation in response['InvalidationList']['Items']: # 只检查状态为InProgress的请求 if invalidation['Status'] != 'InProgress': continue # 获取该无效请求包含的所有路径 invalidation_paths = invalidation['InvalidationBatch']['Paths']['Items'] # 检查目标路径是否在其中 if target_path in invalidation_paths: return True # 检查是否还有下一页 marker = response['InvalidationList'].get('NextMarker') if not marker: break return False def lambda_handler(event, context): # 遍历所有S3事件记录(修复原代码覆盖最后一条记录的问题) for item in event["Records"]: path = "/" + item["s3"]["object"]["key"] print(f"Processing path: {path}") # 检查是否存在正在进行的无效请求 if has_in_progress_invalidation(path): print(f"Found InProgress invalidation for {path}, skipping creation") continue # 创建新的无效请求 print(f"Creating new invalidation for {path}") cloudfront.create_invalidation( DistributionId=DISTRIBUTION_ID, InvalidationBatch={ 'Paths': { 'Quantity': 1, 'Items': [path] }, 'CallerReference': str(time.time()) } )
关键修改说明
- 新增检查函数:
has_in_progress_invalidation负责遍历目标分发下的所有无效请求,处理分页场景,筛选出状态为InProgress且包含目标路径的请求。 - 修复事件遍历问题:原代码循环遍历S3记录时会覆盖
path变量,改为逐个处理每个记录的对象路径。 - 条件创建逻辑:在创建无效请求前先调用检查函数,若存在符合条件的正在进行的请求则跳过,否则创建新请求。
内容的提问来源于stack exchange,提问作者sapientZero
相关产品推荐
相关产品推荐

