如何解决ERPNext中使用smtp.gmail.com发送批量邮件的连接问题?
解决ERPNext批量发送邮件时SMTP连接意外关闭的问题
问题根源分析
- Gmail SMTP限制触发:Gmail免费账户对批量邮件的发送频率、并发连接数有严格限制,服务器环境下连续发送容易触发反垃圾/限流机制,本地因发送频率低或IP环境不同未触发。
- 连接复用不足:Frappe默认SMTP客户端在高并发批量发送时,可能未正确复用连接,频繁创建新连接导致被Gmail阻断。
- 队列配置不合理:使用
short队列会导致高并发请求,短时间内大量SMTP连接请求直接触发Gmail的限流。
针对性解决方案
1. 调整Gmail账户配置
- 如果使用免费Gmail账户,建议更换为Google Workspace账户,Workspace提供更高的批量发送限额,更适合企业级邮件场景。
- 开启两步验证后,必须使用App Password替代账户密码进行SMTP认证;未开启两步验证的账户,需启用“不太安全的应用访问”(仅旧账户支持)。
2. 优化邮件发送逻辑
- 批量合并收件人:若邮件内容一致,避免循环单独调用
enqueue,改为一次性发送给所有收件人,减少SMTP连接次数:# 收集所有收件人后批量发送 all_recipients = [] for ctx in context_list: all_recipients.extend(get_recipients(ctx.get('email'))) frappe.enqueue( queue="long", method=frappe.sendmail, recipients=all_recipients, sender="info@example.com", subject=frappe.render_template(email_template.subject, ctx), message=message, now=False, ) - 调整队列类型:将
queue="short"改为queue="long",并在Frappe后台降低short队列的worker数量,控制并发请求量。
3. 配置Frappe SMTP连接池
在站点的site_config.json中添加SMTP连接池相关配置,提升连接复用率:
{ "email_smtp_use_tls": 1, "email_smtp_port": 587, "email_smtp_server": "smtp.gmail.com", "email_smtp_username": "your-account@gmail.com", "email_smtp_password": "your-app-password", "smtp_keep_alive": true, "smtp_max_connections": 5, "smtp_connection_timeout": 30 }
4. 添加发送延迟与重试
- 分批次发送邮件,每批发送后添加短暂延迟,避免触发频率限制:
import time batch_size = 50 all_recipients = get_all_recipients() # 替换为你的收件人获取逻辑 for idx in range(0, len(all_recipients), batch_size): batch_recipients = all_recipients[idx:idx+batch_size] frappe.enqueue( queue="long", method=frappe.sendmail, recipients=batch_recipients, sender="info@example.com", subject=subject, message=message, now=False, retry=3 # 设置重试次数 ) time.sleep(10) # 每批发送后暂停10秒
5. 排查服务器网络环境
- 用
telnet smtp.gmail.com 587测试服务器到Gmail SMTP的连通性,确保未被防火墙/安全组拦截。 - 同步服务器系统时间到NTP服务器,时间偏差过大可能导致SMTP认证失败。
内容的提问来源于stack exchange,提问作者hizbul25
相关产品推荐
相关产品推荐

