import smtplib
with smtplib.SMTP_SSL(host, 465) as s:
s.login(user, pwd)
for m in batch:
s.sendmail(sender, m["to"], m["raw"])
群发任务一启动,网关日志刷满 too many connections,客户端这边报 SMTPServerDisconnected。并发设的是 200,网关单 IP 上限 20。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:每个发信线程各建一条 SMTP 连接,发完不关,连接数随线程数线性上涨。网关按来源 IP 限连接,超出的直接拒。线程池大小和连接池大小被当成了同一个概念。
「SMTP 连接池打满」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。同一份配置存在多处的,先确认改的是被加载的那一份。
新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
处理上按这个顺序:把并发降到网关上限以内 或者走多 IP 分摊;改成连接复用 一个连接连续发多封;发完显式 quit 并归还连接 不要靠 GC;压测时盯网关侧的活动连接数。
确认没问题再收工,群发期间网关活动连接稳定在 15 条以内,不再出现 too many connections,任务总耗时只增加 10%。
