You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Celery定时任务调用AWS S3 upload_file超时问题及解决诉求

Celery定时任务中AWS S3上传超时问题排查与解决

问题描述

我编写了AWS S3文件上传方法,本地直接运行可正常上传文件,但整合到Celery定时任务执行时,调用s3_client.upload_file()出现连接超时。

上传方法代码

def upload_file_to_aws(file_name):
    """Upload a file to an S3 bucket
    :param file_name: File to upload
    :return: True if file was uploaded, else False
    """

    bucket = get_bucket()
    # If S3 object_name was not specified, use file_name
    object_name = file_name.split("/")[-1]
    
    # Upload the file
    s3_client = boto3.client(
        "s3",
        aws_access_key_id=AWS_ACCESS_KEY_ID,
        aws_secret_access_key=AWS_SECRET_ACCESS_KEY
    )
    ce_logger.info(f"s3_client:{s3_client}")
    try:
        s3_client.upload_file(file_name, bucket, object_name)
    except Exception as e:
        logger.info(e)
        return False
    return True

Celery日志报错

[the 2022-12-08 13:40:03, 205: INFO/ForkPoolWorker-1]  project.invoice.tasks.download_gmail_attachment_create_invoice[14b98680-7f38-45fb-9dbe-283330c304b0]: s3_client:<botocore.client.S3 object at 0x7f0a8a5f35e0>
[13:45:11 2022-12-08, 162: INFO/ForkPoolWorker-1]  project.invoice.tasks.download_gmail_attachment_create_invoice[14b98680-7f38-45fb-9dbe-283330c304b0]:  Connect timeout on endpoint URL: "https://karbon-text.s3.ap-south-1.amazonaws.com/upload_aSZcLIM.pdf"

Celery定时任务配置

app.conf.beat_schedule = {
    "download_gmail_attachment_create_invoice": {
        "task": "project.invoice.tasks.download_gmail_attachment_create_invoice",
        "schedule": crontab(minute="*/10"),
    },
}

任务函数代码

@shared_task
def download_gmail_attachment_create_invoice():
    file_name = get_file_name()
    upload_file_to_aws(file_name)

可能原因

  • 网络环境限制:本地网络可正常访问S3,但Celery Worker所在服务器/容器的防火墙、安全组或VPC配置限制了出站流量到S3服务端口(443)。
  • Fork进程连接池问题:Celery默认用Fork模式启动Worker,子进程会继承父进程的Socket连接,导致boto3客户端的连接池在子进程中无法正常工作。
  • 未配置超时与重试:boto3默认超时参数较长,网络不稳定时易触发超时,且代码未设置重试机制。

解决方案

1. 验证网络连通性

登录Celery Worker所在服务器,执行命令测试S3 Endpoint连通性:

curl -v https://karbon-text.s3.ap-south-1.amazonaws.com

若无法连接,需:

  • 调整服务器防火墙/安全组,允许出站访问443端口;
  • 若在VPC环境,配置S3网关端点(Gateway Endpoint),让VPC内资源直接访问S3。

2. 优化boto3客户端初始化

在上传函数内延迟初始化客户端,并添加超时与重试配置,确保每个Worker进程使用独立的客户端实例:

s3_client = boto3.client(
    "s3",
    aws_access_key_id=AWS_ACCESS_KEY_ID,
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    config=boto3.session.Config(
        connect_timeout=10,  # 连接超时(秒)
        read_timeout=30,     # 读取超时(秒)
        retries={"max_attempts": 3}  # 重试次数
    )
)

3. 确保文件可访问性

确认get_file_name()返回的文件路径在Worker进程中存在且可读,避免临时文件被提前删除或Worker无读取权限。

4. 添加Celery任务重试机制

给任务绑定重试逻辑,遇到超时异常时自动重试:

@shared_task(bind=True, max_retries=3)
def download_gmail_attachment_create_invoice(self):
    file_name = get_file_name()
    try:
        upload_success = upload_file_to_aws(file_name)
        if not upload_success:
            raise Exception("S3上传失败")
    except Exception as e:
        self.retry(exc=e, countdown=60)  # 60秒后重试

内容的提问来源于stack exchange,提问作者hans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:05:23