Назад | Перейти на главную страницу

SMTP-серверу требуется более 30 секунд, чтобы принять сообщение, как это сделать быстрее?

Один из наших SMTP-серверов медленно принимает электронные письма, вот типичный результат (время ответа 30+ секунд) клиентского скрипта smtp:

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

Рубиновый скрипт:

message = <<MESSAGE_END
From: One <one@example.com>
To: Two <two@example.com>
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, 'one@example.com', ['two@example.com']
  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 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: me@example.com
250 2.1.0 me@example.com... Sender ok
RCPT TO: someone@example.com
250 2.1.5 someone@example.com... 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: me@example.com
(- 10 second delay -)
250 2.1.0 me@example.com... Sender ok

ОБНОВЛЕНИЕ снова, похоже, задержка очень похожа на описанную в книге 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

Я бы посоветовал, если возможно, выполнить некоторые ручные команды для взаимодействия с 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: youremail@yourdomain.com and hit enter
     Replace youremail@yourdomain.com with your email address
• Type RCPT TO: email@domain.com and hit enter
     Replace email@domain.com 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: программное обеспечение, файлы конфигурации, конфигурацию ОС.

Почтовый сервер может выполнять множество проверок адреса отправителя. Большинство этих проверок связано с поиском в DNS. Если DNS неправильно настроен на сервере или если неправильно настроен домен отправителя, время ожидания некоторых из этих запросов DNS может истечь. Обратный DNS на клиентском IP также мог быть неправильно настроен, так что время поиска истекло.

Две проверки, которые иногда выполняются, связаны с другим сетевым соединением.

Почтовый сервер может подключаться к демону аутентификации по IP-адресу клиента. Если клиент использует неправильно настроенный брандмауэр, пакет SYN, отправленный на порт 113, теряется. После нескольких попыток сервер откажется.

Почтовый сервер может также подключиться к MX для домена отправителя, чтобы проверить, существует ли адрес отправителя. Эта конкретная проверка используется редко, поскольку при неправильном выполнении она может потерпеть неудачу.

Чтобы определить, что из вышеперечисленного имеет место, нужно проверить сетевой трафик. Эту проверку можно выполнить с помощью tcpdump или wirehark.

Попробуйте прикрепить strace к вашему процессу sendmail и посмотрите, что он дает вам, когда вы вручную набираете почту из команды (конечно, вы должны убедиться, что к тому времени никто другой не использует службу SMTP. Это должно дать вам лучшее представление о том, какой отправитель проверка выполняется медленно.Если не знаете, как использовать Стив, эта простая запись в блоге может оказаться некоторой помощью (особенно главы 3 и 4).

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

Тот факт, что вы видите задержку между «MAIL FROM» и следующей командой, означает, что sendmail проверяет адрес отправителя. это делает настоятельно предлагает проблему с DNS / сетью, но вы говорите, что поиск DNS вручную - это нормально. Если этот почтовый сервер использует управляемый вами DNS-сервер, не могли бы вы попробовать включить ведение журнала запросов, чтобы увидеть, какие вопросы задаются (и сколько времени DNS-сервер отвечает)?

Вы говорите «один из наших SMTP-серверов медленно принимает электронные письма». Это означает, что другие ваши SMTP-серверы не демонстрируют такого поведения. Так ли это? Если да, то чем отличается этот?

Если проблемный сервер используется в производственной среде, вы можете попробовать запустить дополнительный экземпляр sendmail, прослушивающий другой порт, чтобы вы могли повысить уровень отладки. Альтернативой было бы использование strace, как предлагает alxgomz. Если вы устанавливаете первоначальное соединение с помощью telnet, вы можете просто ограничить дочерний процесс, обрабатывающий ваше сообщение, а не все SMTP-соединения.

Вы используете example.com в своем тесте (как указано в вашем скрипте ruby)? Возможно, у вас возникли проблемы, когда нет записей MX, которые нужно вернуть. Вы пробовали это с реальными адресами электронной почты? Задержка только для определенных доменов?