Golang批量发送邮件方案
最近需要用Golang实现一个批量发送邮件的功能,但不太清楚如何高效处理。主要需求是:
- 支持并发发送大量邮件(比如几千封)
- 需要跟踪发送成功/失败的状态
- 避免被邮件服务器当作垃圾邮件拦截
目前试了net/smtp标准库,但性能不太理想,而且缺乏错误处理机制。有没有成熟的方案或开源库推荐?比如是否需要结合channel和goroutine来实现并发控制?或者有其他更高效的方式?
2 回复
使用Golang批量发送邮件,推荐以下方案:
-
核心库选择
- 标准库
net/smtp:轻量但功能简单 - 第三方库
gomail.v2:功能丰富,支持附件和HTML
- 标准库
-
实现方案
// 使用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)
}
}
-
优化建议
- 使用连接池复用SMTP连接
- 控制并发数量(建议5-10个goroutine)
- 添加失败重试机制
- 记录发送日志和统计
-
注意事项
- 避免被识别为垃圾邮件
- 注意服务商的发送频率限制
- 敏感信息不要硬编码在代码中
简单场景用标准库,复杂需求推荐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)
}
}
优化建议
- 并发发送:使用goroutine提高发送效率
- 错误处理:记录发送失败的邮件以便重试
- 速率限制:避免被邮件服务器限制
- 模板支持:使用html/template生成邮件内容
gomail库功能更完善,支持附件、HTML内容等,推荐在生产环境中使用。

