Databricks定时任务发送重复邮件问题排查求助
重复发送邮件的排查与修复
一、代码中的潜在问题
重复导入模块:代码里重复导入了
MIMEMultipart,虽不影响功能,但建议删除重复行:from email.mime.multipart import MIMEMultipart # 保留一行即可收件人列表处理隐患:
- 若
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())
- 若
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
相关产品推荐
相关产品推荐

