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

如何在Celery定时任务中每发送20封邮件休眠1秒?

实现Celery任务每发送20封邮件休眠1秒

解决方案思路

  1. 先从数据库筛选出due_date为今日的记录,提取目标邮箱列表(或逐个处理每条记录)
  2. 将邮件发送任务按每20封一组拆分,每完成一组发送后(非最后一组)执行1秒休眠;若需针对单条记录定制邮件内容,则逐个发送并计数,每发送20封触发休眠。

代码实现(批量发送场景)

适用于所有邮件模板数据一致,仅收件人不同的情况:

from datetime import date
import time
from celery import app  # 根据你的Celery配置导入
from your_app.models import YourModel  # 替换为你的数据库模型类
from your_email_utils import send_email_from_template  # 导入邮件发送函数

@app.task(bind=True)
def send_email_reminder_on_due_date(self):
    # 1. 获取今日到期的记录
    today = date.today()
    records = YourModel.objects.filter(due_date=today)
    
    # 2. 提取所有收件邮箱
    email_list = [record.email for record in records]
    # 通用模板数据(若需每条记录定制,需调整为逐行生成)
    template_data = {
        "greeting": "您好",
        "subject_prefix": "到期提醒"
        # 补充你的模板变量
    }
    
    # 3. 按每20封拆分批次
    batch_size = 20
    email_batches = [email_list[i:i+batch_size] for i in range(0, len(email_list), batch_size)]
    
    # 4. 逐批次发送并休眠
    for idx, batch in enumerate(email_batches):
        send_email_from_template(
            subject_template_path='emails/subject.txt',
            body_template_path='emails/template.html',
            template_data=template_data,
            to_email_list=batch,
            fail_silently=False,
            content_subtype='html'
        )
        
        # 最后一批无需休眠
        if idx != len(email_batches) - 1:
            time.sleep(1)

代码实现(单条定制场景)

适用于每条记录对应不同模板内容的情况:

from datetime import date
import time
from celery import app
from your_app.models import YourModel
from your_email_utils import send_email_from_template

@app.task(bind=True)
def send_email_reminder_on_due_date(self):
    today = date.today()
    records = YourModel.objects.filter(due_date=today)
    
    batch_size = 20
    send_count = 0
    total_records = len(records)
    
    for record in records:
        # 为当前记录生成专属模板数据
        template_data = {
            "username": record.username,
            "due_task": record.task_name,
            "due_date": record.due_date.strftime("%Y-%m-%d")
            # 补充个性化变量
        }
        
        # 发送单封邮件
        send_email_from_template(
            subject_template_path='emails/subject.txt',
            body_template_path='emails/template.html',
            template_data=template_data,
            to_email_list=[record.email],
            fail_silently=False,
            content_subtype='html'
        )
        
        send_count += 1
        # 每发送20封且未到最后一封时休眠
        if send_count % batch_size == 0 and send_count != total_records:
            time.sleep(1)

注意事项

  • 替换代码中的YourModel为实际的数据库模型类,确保字段名(如email、task_name)与你的模型匹配
  • 若使用Celery多进程/多线程worker,每个worker进程会独立处理分配到的任务批次,休眠逻辑仅作用于当前进程内的任务流
  • time.sleep(1)会阻塞当前worker进程,若任务量极大,可根据实际情况调整休眠时长或批次大小

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:55:20