项目中有一个需求是监控系统性能并发送邮件,考虑到配置代理邮箱发送邮件太重量级,并且繁琐复杂,频繁发送邮件还有IP被禁之虞。所以选择sendmail来发送邮件,简单粗暴。
sendmail的使用方法
linux下安装sendmail和sendmail.service,启动sendmail.service。貌似使用mail命令发送邮件更多,使用sendmail命令发送html格式邮件的方法如下:
echo '<html><body><h4>当前系统中产生一条告警信息,请您知晓</h4></body></html>'|formail -I "From: service" -I "To:$mailList" -I "MIME-Version:1.0" -I "Content-type:text/html;charset=utf-8" -I "Subject:monitor" |sendmail -toi
$mailList是收件人地址,如果由多个收件人,用”,”分隔。有时使用这个命令会被当作垃圾邮件,这时使用sendmail -toi $mailList
会解决。其他诸如乱码问题可通过设置编码来解决,参考sendmail+formail乱码这篇文章。
formail
命令用来组装邮件头。可以看一下formail之后的邮件格式:
From: service
To: test@163.com
MIME-Version:1.0
Content-type:text/html;charset=utf-8
Subject:monitor
<html><body><h4>当前系统中产生一条告警信息,请您知晓</h4></body></html>
所以我们可以把邮件按照上述格式写到文件里,然后通过cat mail.txt|sendmail -toi
发送。
如果你的hostname为默认的localhost的话,你可能会得到一个错误:dsn=5.0.0, stat=Service unavailable
,这是由于默认使用root@localhost.localdomain发件,绝大多数邮箱都会拒收。
解决办法:修改hostname,修改/etc/hosts
文件,添加你的hostname;修改/etc/sysconfig/network
文件,改成HOSTNAME=yourhostname
,重启sendmail.service服务即可。
通过java调用sendmail
通过java调用shell命令的方法是Runtime.getRuntime().exec(command)
,下面直接上代码:
sendmail的反向解析
测试时发现,调用sendmail发邮件,发着发着突然收不到邮件了。于是查看sendmail的状态:
systemctl status sendmail
查看状态和sendmail -bp
查看sendmail队列,结果发现:发邮件的请求都在队列里面排队积压,就是发不出去,如下:
[root@mycentos ~]# sendmail -bp
:call <SNR>110_SparkupNext()
/var/spool/mqueue (22 requests)
-----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient-----------
u9Q36LgF014458* 469 Wed Oct 26 11:08 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q37L92014515 469 Wed Oct 26 11:09 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q38LYx014576 469 Wed Oct 26 11:10 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q39L8e014657 469 Wed Oct 26 11:11 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3ALl5014719 469 Wed Oct 26 11:12 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3BLY7014775 469 Wed Oct 26 11:13 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3CLwF014832 469 Wed Oct 26 11:14 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3DLlR014890 469 Wed Oct 26 11:15 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3ELVj014995 469 Wed Oct 26 11:16 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3FLJV015053 469 Wed Oct 26 11:17 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3GLal015110 469 Wed Oct 26 11:18 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
<vosamo007@163.com>
<buptlsl@163.com>
u9Q3HLwh015220 469 Wed Oct 26 11:19 <root@mycentos.com>
8BITMIME (host map: lookup (163.com): deferred)
其中的host map: lookup (163.com): deferred
,这表示发送邮件出现了延迟,网上说导致这个问题的原因是sendmail默认会进行反向解析,而我自己的机器上没有合法的域名和MX解析记录。解决的办法很简单,打开文件/etc/mail/sendmail.cf
,找到#0 ResolverOptions=+AAONLY
这一行,把注释去掉就可以了。虽然问题是解决了,但是还不是很明白其中的原因,为什么反向地址解析和发邮件延迟会有关系呢?后续研究一下这个问题再写一篇文章吧。
另外,邮件队列中积压的请求删除的话,只需要把/var/spool/mqueue/
下面的文件全部删除就可以了。