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

如何提升SMTP消息发送速度?多次调用延迟且线程方案失效

优化SMTP消息发送速度的解决方案

问题根源

原代码每次调用send_message都会重复执行SMTP连接建立、TLS握手、登录操作,这些步骤本身耗时较长,连续调用多次会累积延迟,导致消息发送间隔过大。之前的线程方案未成功,大概率是因为每个线程仍重复创建独立连接,反而增加了系统开销和邮箱限流风险。

核心优化方案:复用SMTP连接

最有效的优化方式是只建立一次SMTP连接,用同一个连接发送多条消息,省去重复连接、登录的耗时步骤。

1. 封装复用连接的客户端类

import smtplib

# 假设已定义以下全局变量
CARRIERS = {
    "att": "@mms.att.net",
    "verizon": "@vtext.com"
}
EMAIL = "your_email@gmail.com"
PASSWORD = "your_app_password"  # Gmail需使用应用专用密码,而非登录密码

class SMTPClient:
    def __init__(self, smtp_server, smtp_port, email, password):
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
        self.email = email
        self.password = password
        self.server = None

    def connect(self):
        """建立SMTP连接并完成登录"""
        self.server = smtplib.SMTP(self.smtp_server, self.smtp_port)
        self.server.starttls()
        self.server.login(self.email, self.password)

    def send_message(self, phone_number, carrier, message):
        """发送单条消息,需先调用connect()建立连接"""
        if not self.server:
            raise RuntimeError("请先调用connect()初始化连接")
        recipient = phone_number + CARRIERS[carrier]
        self.server.sendmail(self.email, recipient, message)

    def close(self):
        """关闭SMTP连接,避免资源泄漏"""
        if self.server:
            self.server.quit()

2. 批量发送示例

# 初始化客户端并建立一次连接
client = SMTPClient("smtp.gmail.com", 587, EMAIL, PASSWORD)
client.connect()

try:
    # 一次性发送多条消息,复用同一连接
    client.send_message("1234567890", "att", "第一条消息")
    client.send_message("0987654321", "verizon", "第二条消息")
    client.send_message("1122334455", "att", "第三条消息")
finally:
    # 发送完成后必须关闭连接
    client.close()

线程异步优化方案(正确实现)

如果需要异步提交发送任务,可采用单线程复用连接+消息队列的方式,避免多线程竞争连接资源:

import queue
import threading

# 创建消息队列用于存放待发送任务
message_queue = queue.Queue()

def message_worker(client):
    """工作线程:从队列取任务并复用连接发送"""
    while True:
        try:
            phone_num, carrier, msg = message_queue.get()
            if phone_num is None:  # 接收退出信号
                break
            client.send_message(phone_num, carrier, msg)
            message_queue.task_done()
        except Exception as e:
            print(f"消息发送失败: {str(e)}")
            message_queue.task_done()

# 初始化客户端并启动工作线程
client = SMTPClient("smtp.gmail.com", 587, EMAIL, PASSWORD)
client.connect()
worker_thread = threading.Thread(target=message_worker, args=(client,))
worker_thread.start()

# 提交发送任务到队列
message_queue.put(("1234567890", "att", "异步发送第一条"))
message_queue.put(("0987654321", "verizon", "异步发送第二条"))
message_queue.put(("1122334455", "att", "异步发送第三条"))

# 等待所有任务完成,发送退出信号并关闭资源
message_queue.join()
message_queue.put((None, None, None))
worker_thread.join()
client.close()

额外注意事项

  • Gmail权限设置:需开启两步验证并创建应用专用密码,避免登录失败。
  • 发送频率限制:Gmail普通账户单日发送上限为500条,短时间内大量发送可能触发临时限流,若发送量较大需分批次控制速率。
  • 连接异常处理:实际使用中需添加连接重连逻辑,避免因网络波动导致发送失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:34:52