Golang批量发送邮件方案

最近需要用Golang实现一个批量发送邮件的功能,但不太清楚如何高效处理。主要需求是:

  1. 支持并发发送大量邮件(比如几千封)
  2. 需要跟踪发送成功/失败的状态
  3. 避免被邮件服务器当作垃圾邮件拦截

目前试了net/smtp标准库,但性能不太理想,而且缺乏错误处理机制。有没有成熟的方案或开源库推荐?比如是否需要结合channel和goroutine来实现并发控制?或者有其他更高效的方式?

2 回复

使用Golang批量发送邮件,推荐以下方案:

  1. 核心库选择

    • 标准库 net/smtp:轻量但功能简单
    • 第三方库 gomail.v2:功能丰富,支持附件和HTML
  2. 实现方案

// 使用gomail示例
dialer := gomail.NewDialer("smtp.qq.com", 587, "sender@qq.com", "auth-code")
for _, recipient := range recipients {
    m := gomail.NewMessage()
    m.SetHeader("From", "sender@qq.com")
    m.SetHeader("To", recipient.Email)
    m.SetHeader("Subject", subject)
    m.SetBody("text/html", content)
    
    if err := dialer.DialAndSend(m); err != nil {
        log.Printf("发送失败 %s: %v", recipient.Email, err)
    }
}
  1. 优化建议

    • 使用连接池复用SMTP连接
    • 控制并发数量(建议5-10个goroutine)
    • 添加失败重试机制
    • 记录发送日志和统计
  2. 注意事项

    • 避免被识别为垃圾邮件
    • 注意服务商的发送频率限制
    • 敏感信息不要硬编码在代码中

简单场景用标准库,复杂需求推荐gomail,记得处理好错误和性能优化。

更多关于Golang批量发送邮件方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中实现批量发送邮件,推荐使用标准库net/smtp或第三方库gomail。以下是两种方案的实现:

方案一:使用标准库 net/smtp

package main

import (
    "fmt"
    "net/smtp"
    "strings"
)

type Email struct {
    From    string
    To      []string
    Subject string
    Body    string
}

func sendBatchEmails(emails []Email, smtpHost string, smtpPort string, username string, password string) error {
    auth := smtp.PlainAuth("", username, password, smtpHost)
    
    for _, email := range emails {
        msg := buildMessage(email)
        err := smtp.SendMail(
            smtpHost+":"+smtpPort,
            auth,
            email.From,
            email.To,
            []byte(msg),
        )
        if err != nil {
            return fmt.Errorf("发送邮件失败: %v", err)
        }
        fmt.Printf("成功发送邮件到: %s\n", strings.Join(email.To, ", "))
    }
    return nil
}

func buildMessage(email Email) string {
    msg := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\r\n"
    msg += fmt.Sprintf("From: %s\r\n", email.From)
    msg += fmt.Sprintf("To: %s\r\n", strings.Join(email.To, ";"))
    msg += fmt.Sprintf("Subject: %s\r\n", email.Subject)
    msg += "\r\n" + email.Body
    return msg
}

方案二:使用 gomail 库(推荐)

首先安装gomail:

go get gopkg.in/gomail.v2
package main

import (
    "gopkg.in/gomail.v2"
)

func sendBatchEmailsWithGomail(emails []Email, smtpHost string, smtpPort int, username string, password string) error {
    d := gomail.NewDialer(smtpHost, smtpPort, username, password)
    
    for _, email := range emails {
        m := gomail.NewMessage()
        m.SetHeader("From", email.From)
        m.SetHeader("To", email.To...)
        m.SetHeader("Subject", email.Subject)
        m.SetBody("text/html", email.Body)
        
        if err := d.DialAndSend(m); err != nil {
            return fmt.Errorf("发送邮件失败: %v", err)
        }
        fmt.Printf("成功发送邮件到: %v\n", email.To)
    }
    return nil
}

使用示例

func main() {
    emails := []Email{
        {
            From:    "sender@example.com",
            To:      []string{"user1@example.com", "user2@example.com"},
            Subject: "测试邮件",
            Body:    "<h1>Hello World</h1><p>这是一封测试邮件</p>",
        },
        // 更多邮件...
    }
    
    // 使用gomail发送
    err := sendBatchEmailsWithGomail(emails, "smtp.example.com", 587, "username", "password")
    if err != nil {
        panic(err)
    }
}

优化建议

  1. 并发发送:使用goroutine提高发送效率
  2. 错误处理:记录发送失败的邮件以便重试
  3. 速率限制:避免被邮件服务器限制
  4. 模板支持:使用html/template生成邮件内容

gomail库功能更完善,支持附件、HTML内容等,推荐在生产环境中使用。

回到顶部