我们的一个 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")
我怎样才能提高性能?
更新(包含 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 FROM
需要RCPT TO
大约 20 秒才能OK
返回。其他命令会立即响应。
启用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 问题,因为dig
响应nslookup
很快:
# 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
答案1
如果可能的话,我建议执行一些手动命令来与 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
答案2
您没有告诉我们有关您的配置的任何信息,但是根据您的“日志”,连接时间和信封处理时间都没有问题,只有邮件正文的处理比较慢。
因此,这里有两种解释,按概率排序:
- 您有一个邮件过滤器(spamassassin 或其他程序),用于处理所有传入的电子邮件。这就是您的问题所在。
- 您的服务器的邮件队列位于网络共享上,该服务的访问速度极慢。
如果您需要更多线索,请详细说明您的 smtp 配置:软件、配置文件、操作系统配置。
答案3
邮件服务器可以对发件人地址执行大量验证。大多数验证都涉及 DNS 查找。如果服务器上的 DNS 配置错误或发件人域配置错误,则其中一些 DNS 查找可能会超时。客户端 IP 上的反向 DNS 也可能配置错误,导致查找超时。
有时执行的两项检查涉及其他网络通信。
邮件服务器可能会连接到客户端 IP 地址上的身份验证守护程序。如果客户端使用配置错误的防火墙,则发送到端口 113 的 SYN 数据包会丢失。经过几次尝试后,服务器将放弃。
邮件服务器也可能连接到发件人域的 MX 以验证发件人地址是否存在。这种特殊的检查很少使用,因为如果操作错误,可能会失败。
要确定上述哪种情况,需要检查网络流量。可以使用 tcpdump 或 wireshark 进行检查。
答案4
您看到“MAIL FROM”和下一个命令之间存在延迟,这意味着 sendmail 正在验证发件人地址。这做强烈建议 DNS/网络问题,但您说手动 DNS 查找没问题。如果此邮件服务器使用您控制的 DNS 服务器,您可以尝试打开查询日志来查看正在询问哪些问题(以及 DNS 服务器需要多长时间才能响应)吗?
您说“我们的一个 SMTP 服务器接收电子邮件的速度很慢”。这意味着您的其他 SMTP 服务器没有出现此行为。是这样吗?如果是这样,这个有什么不同?
如果问题服务器正在生产中使用,您可能希望尝试启动一个额外的 sendmail 实例,监听不同的端口,以便调高调试级别。另一种方法是使用 strace,正如 alxgomz 建议的那样。如果您使用 telnet 建立初始连接,则可以只 strace 处理消息的子进程,而不是所有 SMTP 连接。