业务需求:
需要定期给注册会员发送广告,问卷等邮件,每天需要完成百万级的邮件发送。
服务器:
若干台postfix服务器
遇到问题:
对于每天百万级的邮件发送任务,postfix服务器很容易完成,Java客户端包含发送时的业务逻辑处理时间,多起几个线程也很容易做到。
但是,如果发送速度过快,会被邮件服务商列入黑名单而拒收邮件,而每个邮件服务商对接收邮件的速度要求又不一样。
解决方法:
这样,需要针对每个邮件批量发送任务,按照每个邮件服务商能接收的速度来发送邮件。
比如,163每秒3封,sina每秒4封等。
于是我们设计了如下结构的邮件发送系统:
用Redis存储每个域名最后的发送时间,
重复a,b
a) 获得并锁住可发送的域名。
b) 针对每一个可发送域名,
1. 如果相应的域名队列中存在待发送邮件,则发送并更新改域名的最后发送时间。
2. 解锁该域名发送记录。
这样,对邮件队列采用非阻塞队列,提高了系统的并发性。
看似解决了问题,但还是被部分服务商列入了黑名单。
于是对系统进行分析,如下:
这是一个典型的生产者与消费者问题,Java客户端生产的邮件定时推送到Postfix队列,然后Postfix消费队列上的邮件,发送到目标邮件服务器。
生产一封,发送一封的话,不会有任何问题,但如果队列中存在多封,那么向目标邮件服务器投送的速度就无法控制了。
于是检查postfix队列:
postqueue -p
发现确实堆积了一些邮件。
原因:系统运行中,某一封邮件发送的延迟会导致后面的邮件发送都被延迟。
处置方法:
在Java端进行发送速度的控制显然是治标不治本的,于是用Java端同样的逻辑修改PostFix中邮件发送的代码,
用同样的配置文件,最终从根本上解决了控制邮件发送速度的问题。
原文地址:https://www.cnblogs.com/java123vip/p/9005215.html