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%。

作者 9823189