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

Databricks定时任务发送重复邮件问题排查求助

重复发送邮件的排查与修复

一、代码中的潜在问题

  1. 重复导入模块:代码里重复导入了MIMEMultipart,虽不影响功能,但建议删除重复行:

    from email.mime.multipart import MIMEMultipart  # 保留一行即可
    
  2. 收件人列表处理隐患:

    • 若cc或bcc为空字符串,split(",")会生成[""]空地址项,可能触发邮件服务器异常逻辑。建议添加非空校验与清洗:
      rcpt = []
      if bcc:
          rcpt.extend([addr.strip() for addr in bcc.split(",") if addr.strip()])
      if cc:
          rcpt.extend([addr.strip() for addr in cc.split(",") if addr.strip()])
      if recipient:
          rcpt.append(recipient.strip())
      
  3. SMTP连接未用上下文管理器:当前手动调用server.close(),若发送过程中抛出异常,可能导致连接未正常关闭。改用with语句自动管理连接更可靠:

    with smtplib.SMTP('smtp.sendgrid.net', 587) as server:
        server.ehlo()
        server.starttls()
        server.login("apikey", dbutils.secrets.get(scope="XXXX", key="XXXX"))
        # 邮件构建与发送逻辑
        server.sendmail(sender, rcpt, msg.as_string())
    

二、重复发送的核心原因排查

结合“手动执行正常、定时任务重复发送”的现象,重点查以下几点:

1. 函数被重复调用

检查Databricks定时任务对应的作业代码,确认是否两次调用了SendEmail函数——比如遍历收件人时重复触发,或脚本中误写两次SendEmail(...)调用。

2. Databricks作业重试机制

Databricks定时任务默认可能开启失败重试,若第一次发送因网络波动、超时触发重试,会导致重复发件。可在作业配置中查看“重试策略”,将重试次数设为0,或确保发送逻辑幂等。

3. 收件人列表重复

若rcpt列表存在重复地址(比如recipient已在cc中),邮件服务器会向该地址发送两次。建议构建列表时去重:

rcpt = list(set(rcpt))  # 去重,不影响邮件发送逻辑

4. SendGrid配置验证

检查SendGrid控制台的投递设置,确认未开启可能导致重复投递的选项,此情况概率较低,因手动发送正常。

三、修复后的完整代码示例

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from datetime import date
import smtplib


def SendEmail(recipient, subject, message_records, attach, cc, bcc, df):
    sender = dbutils.secrets.get(scope="XXXX", key="XXXX")
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = "noreply@noreply.com"
    msg['To'] = recipient
    if cc:
        msg['cc'] = cc

    # 构建并清洗收件人列表
    rcpt = []
    if bcc:
        rcpt.extend([addr.strip() for addr in bcc.split(",") if addr.strip()])
    if cc:
        rcpt.extend([addr.strip() for addr in cc.split(",") if addr.strip()])
    if recipient:
        rcpt.append(recipient.strip())
    rcpt = list(set(rcpt))  # 去重

    # 构建HTML邮件内容
    message = f"""
<html>
  <body>
       Good morning, <br> <br>
       
     {message_records}<br> <br>
       
       Thank you and have a wonderful day!
  </body>
</html>
"""
    msg.attach(MIMEText(message, 'html'))

    # 添加附件逻辑
    if attach == 1:
        filename = f"ASN-{date.today()}.csv"
        attachment = MIMEApplication(df.to_csv(index=False))
        attachment["Content-Disposition"] = f'attachment; filename="{filename}"'
        msg.attach(attachment)

    # 上下文管理器发送邮件
    with smtplib.SMTP('smtp.sendgrid.net', 587) as server:
        server.ehlo()
        server.starttls()
        server.login("apikey", dbutils.secrets.get(scope="XXXX", key="XXXX"))
        server.sendmail(sender, rcpt, msg.as_string())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:45:34