【发布时间】:2022-01-07 23:26:08
【问题描述】:
我有一个s3 存储桶,它将全天接收新文件。每次将新文件上传到存储桶时,我都想将这些下载到我的 ec2 实例。
我已经读到它可以使用sqs 或sns 或lambda。哪一个是最简单的?文件上传到存储桶后,我需要尽快下载文件。
编辑
我基本上每隔几秒或几分钟就会在存储桶中获取 png 图像。每次上传新图像时,我都想在已经运行的实例上下载它。我会做一些人工智能处理。由于图像会不断进入存储桶,因此我想不断将其下载到 ec2 中并尽快处理。 到目前为止,这是我在 Lambda 函数中的代码。
import boto3
import json
def lambda_handler(event, context):
"""Read file from s3 on trigger."""
#print(event)
s3 = boto3.client("s3")
client = boto3.client("ec2")
ssm = boto3.client("ssm")
instanceid = "******"
if event:
file_obj = event["Records"][0]
#print(file_obj)
bucketname = str(file_obj["s3"]["bucket"]["name"])
print(bucketname)
filename = str(file_obj["s3"]["object"]["key"])
print(filename)
response = ssm.send_command(
InstanceIds=[instanceid],
DocumentName="AWS-RunShellScript",
Parameters={
"commands": [f"aws s3 cp {filename} ."]
}, # replace command_to_be_executed with command
)
# fetching command id for the output
command_id = response["Command"]["CommandId"]
time.sleep(3)
# fetching command output
output = ssm.get_command_invocation(CommandId=command_id, InstanceId=instanceid)
print(output)
return
但是我收到以下错误
Test Event Name
test
Response
{
"errorMessage": "2021-12-01T14:11:30.781Z 88dbe51b-53d6-4c06-8c16-207698b3a936 Task timed out after 3.00 seconds"
}
Function Logs
START RequestId: 88dbe51b-53d6-4c06-8c16-207698b3a936 Version: $LATEST
END RequestId: 88dbe51b-53d6-4c06-8c16-207698b3a936
REPORT RequestId: 88dbe51b-53d6-4c06-8c16-207698b3a936 Duration: 3003.58 ms Billed Duration: 3000 ms Memory Size: 128 MB Max Memory Used: 87 MB Init Duration: 314.81 ms
2021-12-01T14:11:30.781Z 88dbe51b-53d6-4c06-8c16-207698b3a936 Task timed out after 3.00 seconds
Request ID
88dbe51b-53d6-4c06-8c16-207698b3a936
当我删除所有与 ssm 相关的行时,它工作正常。是权限问题还是代码有问题?
EDIT2
我的代码正在运行,但在我的 ec2 实例中没有看到任何输出或更改。我应该在主目录中看到一个空文本文件,但我什么也没看到 代码
import boto3
import json
import time
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
"""Read file from s3 on trigger."""
#print(event)
s3 = boto3.client("s3")
client = boto3.client("ec2")
ssm = boto3.client("ssm")
instanceid = "******"
print("HI")
if event:
file_obj = event["Records"][0]
#print(file_obj)
bucketname = str(file_obj["s3"]["bucket"]["name"])
print(bucketname)
filename = str(file_obj["s3"]["object"]["key"])
print(filename)
print("sending")
try:
response = ssm.send_command(
InstanceIds=[instanceid],
DocumentName="AWS-RunShellScript",
Parameters={
"commands": ["touch hi.txt"]
}, # replace command_to_be_executed with command
)
# fetching command id for the output
command_id = response["Command"]["CommandId"]
time.sleep(3)
# fetching command output
output = ssm.get_command_invocation(CommandId=command_id, InstanceId=instanceid)
print(output)
except Exception as e:
logger.error(e)
raise e
【问题讨论】:
-
你能告诉我们更多关于为什么你想每次都下载它吗?文件会以某种方式在实例上处理吗?如果是这样,您的应用程序如何知道新文件已经到达——它是在检查文件,还是需要以某种方式“触发”?您会保留实例上的所有历史文件(这意味着您可以使用
aws s3 sync),还是会在处理后删除文件?请编辑您的问题以提供这些额外的详细信息,以便我们提供适当的建议。 -
@JohnRotenstein 我现在已经添加了问题的详细信息
-
根据@theherk 的 cmets,您的方法似乎不正确。不要将其视为“将文件复制到 EC2”。相反,将其视为“每当新对象出现在 S3 中时,我都想使用 EC2 实例上的代码来处理它”。该代码既可以下载文件 也可以 处理图像。最好的架构方法是让 S3 向 Amazon SQS 队列发送消息,然后您在 EC2 实例上的程序将获取消息、下载文件、处理文件,然后从 SQS 队列中删除消息。这是可扩展的,因为 SQS 将充当待完成工作的缓冲区。
标签: amazon-web-services amazon-s3 amazon-ec2 aws-lambda amazon-sqs