SMTP 服务器需要 30 多秒才能接受一条消息,如何加快速度?

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")

我怎样才能提高性能?

更新(包含 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返回。其他命令会立即响应。

更新,功能('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 问题,因为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

您没有告诉我们有关您的配置的任何信息,但是根据您的“日志”,连接时间和信封处理时间都没有问题,只有邮件正文的处理比较慢。

因此,这里有两种解释,按概率排序:

  1. 您有一个邮件过滤器(spamassassin 或其他程序),用于处理所有传入的电子邮件。这就是您的问题所在。
  2. 您的服务器的邮件队列位于网络共享上,该服务的访问速度极慢。

如果您需要更多线索,请详细说明您的 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 连接。

相关内容