SMTP服务器需要30多秒才能接收邮件,如何使邮件更快?

我们的其中一台SMTP服务器接受电子邮件的速度很慢,以下是smtp客户端脚本的典型输出(响应时间超过30秒):

2014-02-26 11:44:11 +0800 BEGIN 2014-02-26 11:44:11 +0800 LOGGED IN 2014-02-26 11:44:11 +0800 BEFORE SEND 2014-02-26 11:44:59 +0800 AFTER SEND 2014-02-26 11:44:59 +0800 END 

ruby脚本:

 message = <<MESSAGE_END From: One <[email protected]> To: Two <[email protected]> Subject: SMTP e-mail test Testing 123 MESSAGE_END def timelog(msg) puts "#{Time.now} #{msg}" end timelog("BEGIN") Net::SMTP.start(host, 25, 'localhost', username, password, :plain) do |smtp| timelog("LOGGED IN") timelog("BEFORE SEND") smtp.send_message message, '[email protected]', ['[email protected]'] timelog("AFTER SEND") end timelog("END") 

我该如何改善performance?

更新(与DNS时间信息,加载):

 # time dig yahoo.com mx ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.5 <<>> yahoo.com mx ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57858 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;yahoo.com. IN MX ;; ANSWER SECTION: yahoo.com. 528 IN MX 1 mta7.am0.yahoodns.net. yahoo.com. 528 IN MX 1 mta5.am0.yahoodns.net. yahoo.com. 528 IN MX 1 mta6.am0.yahoodns.net. ;; Query time: 5 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Fri Mar 21 12:26:09 2014 ;; MSG SIZE rcvd: 106 real 0m1.013s user 0m0.004s sys 0m0.004s 

top ,这是一个新的服务器,所以几乎没有加载:

 Cpu(s): 0.2%us, 0.0%sy, 0.0%ni, 99.5%id, 0.3%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1903696k total, 1310776k used, 592920k free, 311492k buffers Swap: 4095992k total, 0k used, 4095992k free, 822692k cached 

更新(telnet):

 # telnet 127.0.0.1 25 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 220 m1.example.com ESMTP Sendmail 8.14.4/8.14.4; Tue, 25 Mar 2014 14:47:04 +0800 HELO 127.0.0.1 250 m1.example.com Hello localhost [127.0.0.1], pleased to meet you AUTH LOGIN 334 VXNlcm5hbWU6 bWUuY29t 334 UGFzc3dvcmQ6 cGFzc3dvcmQ= 235 2.0.0 OK Authenticated MAIL FROM: [email protected] 250 2.1.0 [email protected]... Sender ok RCPT TO: [email protected] 250 2.1.5 [email protected]... Recipient ok DATA 354 Enter mail, end with "." on a line by itself Testing 12345 . 250 2.0.0 s2P6l4Dj012326 Message accepted for delivery QUIT 221 2.0.0 m1.example.com closing connection Connection closed by foreign host. 

请注意, MAIL FROMRCPT TO在返回OK之前需要大约20秒。 其他命令立即响应。

UPDATE, FEATURE('delay_checks') :

启用FEATURE('delay_checks')可以将响应时间从30秒改善到10秒。 〜10秒的延迟在MAIL FROM:Sender ok

 MAIL FROM: [email protected] (- 10 second delay -) 250 2.1.0 [email protected]... Sender ok 

再次进行更新,看起来延迟与Bryan Costales的书Sendmail(第258页 )中描述的非常相似:

在这里输入图像说明

这不是一个DNS问题,因为dignslookup反应很快:

 # time nslookup mta5.am0.yahoodns.net Server: 8.8.8.8 Address: 8.8.8.8#53 Non-authoritative answer: Name: mta5.am0.yahoodns.net Address: 66.196.118.240 Name: mta5.am0.yahoodns.net Address: 98.138.112.34 Name: mta5.am0.yahoodns.net Address: 66.196.118.37 Name: mta5.am0.yahoodns.net Address: 98.138.112.32 Name: mta5.am0.yahoodns.net Address: 98.136.217.203 Name: mta5.am0.yahoodns.net Address: 98.138.112.33 Name: mta5.am0.yahoodns.net Address: 98.138.112.38 Name: mta5.am0.yahoodns.net Address: 63.250.192.46 real 0m1.016s user 0m0.001s sys 0m0.006s 

更新与sendmail.mc:

 # cat /etc/mail/sendmail.mc | grep -v "^dnl" divert(-1)dnl include(`/usr/share/sendmail-cf/m4/cf.m4')dnl VERSIONID(`setup for linux')dnl OSTYPE(`linux')dnl define(`confLOG_LEVEL', `14')dnl define(`SMART_HOST', `mail03.example.com')dnl define(`confDEF_USER_ID', ``8:12'')dnl define(`confTO_CONNECT', `1m')dnl define(`confTRY_NULL_MX_LIST', `True')dnl define(`confDONT_PROBE_INTERFACES', `True')dnl define(`PROCMAIL_MAILER_PATH', `/usr/bin/procmail')dnl define(`ALIAS_FILE', `/etc/aliases')dnl define(`STATUS_FILE', `/var/log/mail/statistics')dnl define(`UUCP_MAILER_MAX', `2000000')dnl define(`confUSERDB_SPEC', `/etc/mail/userdb.db')dnl define(`confPRIVACY_FLAGS', `authwarnings,novrfy,noexpn,restrictqrun')dnl define(`confAUTH_OPTIONS', `A y')dnl define(`confCW_FILE', `/etc/mail/local-host-names')dnl define(`confDOMAIN_NAME', `domain.example.com')dnl define(`confMAX_MESSAGE_SIZE',`23271520')dnl TRUST_AUTH_MECH(`LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl define(`confAUTH_MECHANISMS', `LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl define(`confTO_QUEUERETURN', `1d')dnl define(`confTO_IDENT', `0')dnl FEATURE(`delay_checks')dnl FEATURE(`no_default_msa', `dnl')dnl FEATURE(`smrsh', `/usr/sbin/smrsh')dnl FEATURE(`mailertable', `hash -o /etc/mail/mailertable.db')dnl FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable.db')dnl FEATURE(redirect)dnl FEATURE(always_add_domain)dnl FEATURE(use_cw_file)dnl FEATURE(use_ct_file)dnl FEATURE(local_procmail, `', `procmail -t -Y -a $h -d $u')dnl FEATURE(`access_db', `hash -T<TMPF> -o /etc/mail/access.db')dnl FEATURE(`blacklist_recipients')dnl EXPOSED_USER(`root')dnl DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0, Name=MTA M=a')dnl FEATURE(`accept_unresolvable_domains')dnl LOCAL_DOMAIN(`localhost.localdomain')dnl MASQUERADE_AS(`example.com')dnl FEATURE(masquerade_entire_domain)dnl MAILER(smtp)dnl MAILER(procmail)dnl 

我会build议如果可能的话执行一些手动命令来与SMTP服务器交互,看看是什么步骤造成的延迟。

请注意,您应该从运行代码的同一台机器执行此操作。 如果结果很慢,则尝试使用与其他机器相同的命令,以查看它是否与正在发送的机器相关,或者是否与发送的机器相同。

 • Type: telnet smtp.server.com 25 and hit enter The Command will connect to the smtp server on port 25 which is used by the SMTP server to communicate • Type: HELO localhost and hit enter You can type anything instead of localhost like yourdomain.com • Type: MAIL FROM: [email protected] and hit enter Replace [email protected] with your email address • Type RCPT TO: [email protected] and hit enter Replace [email protected] to the email address you want to send the email to • Type: DATA and hit enter • Type: this is a test email and hit enter • Type: . and hit enter • Type: QUIT and hit enter 

你没有告诉我们有关你的configuration的任何信息,但根据你的“日志”,连接时间和信封处理时间都可以,只是邮件正文的处理是慢的。

所以这里有两个解释,按照概率的顺序:

  1. 你有一个邮件filter(spamassassin或其他)处理所有传入的电子邮件。 这是你的问题所在。
  2. 您的服务器的邮件队列位于networking共享,访问速度非常慢。

如果您需要更多的线索,请详细介绍您的smtpconfiguration:软件,configuration文件,操作系统configuration。

邮件服务器可以执行许多发件人地址的validation。 这些validation大多涉及DNS查找。 如果服务器上的DNSconfiguration错误,或发件人域configuration错误,则这些DNS查找中的某些可能会超时。 客户端IP上的反向DNS也可能被错误地configuration,使得查找超时。

有时执行的两项检查涉及其他networking通信。

邮件服务器可以连接到客户端IP地址上的auth守护进程。 如果客户端使用错误configuration的防火墙,则发送到端口113的SYN数据包将丢失。 经过几次尝试后,服务器将放弃。

邮件服务器也可以连接到发件人域的MX,以validation发件人地址是否存在。 这个特殊的检查很less使用,因为如果做错了,它可能会失败。

为了确定上述哪一种情况,需要检查networkingstream量。 这种检查可以使用tcpdump或wireshark完成。

尝试将strace附加到你的sendmail进程,看看它给你什么,你手动input命令的邮件(当然你应该确保没有其他人在那个时候使用SMTP服务,这应该让你更好地了解哪个发送者如果不确定如何使用Steve这个简单的博客文章可能会有帮助(特别是第3章和第4章)。

http://www.hokstad.com/5-simple-ways-to-troubleshoot-using-strace

事实上,你看到“MAIL FROM”和下一个命令之间的延迟意味着sendmail正在validation发件人地址。 这确实强烈build议DNS /networking问题,但你说手工DNS查询是确定的。 如果这个邮件服务器在你的控制下使用一个DNS服务器,你可以尝试打开查询日志logging来查看要问什么问题(以及DNS服务器响应多长时间)?

你说“我们的一个SMTP服务器很慢接受电子邮件”。 这意味着您的其他SMTP服务器不会显示此行为。 是这样吗? 如果有的话,这个有什么不同?

如果问题服务器在生产环境中使用,您可能希望尝试启动另一个端口上监听的sendmail实例,以便调出debugging级别。 另一种方法是像alxgomz所暗示的那样使用strace。 如果使用telnet进行初始连接,则可以对处理消息的subprocess进行置换,而不是对所有SMTP进行连接。

你在testing中使用example.com(如你的ruby脚本所述)? 当没有MXlogging被返回时,也许你遇到了麻烦。 你有没有试过这个真实的电子邮件地址? 只有某些域的延迟?