使用 Perl NET::SMTP 透過 Exim 發送電子郵件,然後透過 Postfix 從特定伺服器發送時速度會變慢

使用 Perl NET::SMTP 透過 Exim 發送電子郵件,然後透過 Postfix 從特定伺服器發送時速度會變慢

我們在 Debian 11 (Bullseye) 上設定了幾台伺服器。我們每天使用 cron 在所有伺服器上定期運行的進程之一是一個 Perl 腳本,它從 MySQL 資料庫讀取資料並發送包含相關資料的電子郵件。電子郵件的數量各不相同,但通常每批 5 到 20 封之間。除了晚上,另一個進程將編譯資訊並準備數百封電子郵件。這些通常都與下一批一起發送。除了我們的一台伺服器上。

我們不久前安裝了該伺服器,最近在其上新增了一個新客戶端。該客戶端產生的電子郵件數量比其他客戶端更高。我們注意到這會導致問題,因為在這台特定的機器上,電子郵件的發送速度不如其他機器。這意味著 Perl 腳本將再次對待處理的電子郵件進行排隊,並且它們將開始堆積。

perl 腳本與本地安裝的 Exim4 進行通訊。我們在所有伺服器上使用的配置都是相同的。這是update-exim4.conf.con文件:

dc_eximconfig_configtype='smarthost'
dc_other_hostnames=''
dc_local_interfaces='127.0.0.1 ; ::1'
dc_readhost='******.com'
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost='1**.***.***.**6'
CFILEMODE='644'
dc_use_split_config='true'
dc_hide_mailname='true'
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'

正如您所看到的,Exim 將連接到我們的另一台伺服器,即運行 postfix 的智慧型主機,每封電子郵件都會傳送到其最終目的地。

我們遇到的問題是,該特定伺服器上的電子郵件將開始以非常快的速度發送(~20/s),然後減慢、停止、凍結並最終停止,並出現以下錯誤:

unable to establish SMTP connection to (localhost) port 25

Trace begun at /usr/share/perl5/Email/Sender/Transport/SMTP.pm line 224
Email::Sender::Transport::SMTP::_throw('Email::Sender::Transport::SMTP=HASH(0x55d021f74620)', 'unable to establish SMTP connection to (localhost) port 25') called at /usr/share/perl5/Email/Sender/Transport/SMTP.pm line 174
Email::Sender::Transport::SMTP::_smtp_client('Email::Sender::Transport::SMTP=HASH(0x55d021f74620)') called at /usr/share/perl5/Email/Sender/Transport/SMTP.pm line 233

據我了解,Exim 首先將電子郵件儲存到磁碟,然後將它們新增到佇列中,然後透過智慧主機發送它們(在我們的例子中)。如果是這種情況,則表示 perl 腳本和 Exim 之間可能存在一些連接問題。我嘗試了很多配置更改,但到目前為止沒有效果。

當我使用該標誌從命令列運行 Exim 時-d+all,我獲得了大量數據。對我來說,有趣的部分在於空白:

[...]
12:33:00.959 394267 postfork: daemon-accept-delivery
12:33:00.959 394266 SMTP>>(close on process exit)
12:33:00.959 394266 >>>>>>>>>>>>>>>> Exim pid=394266 (daemon-accept) terminating with rc=0 >>>>>>>>>>>>>>>>
12:33:00.959 394267 exec /usr/sbin/exim4 -d=0xfff9ffff -MCd daemon-accept-delivery -Mc 1pY9HA-001eZ8-TG
12:33:00.960 394250 child 394266 ended: status=0x0
12:33:00.960 394250   normal exit, 0
12:33:00.960 394250 0 SMTP accept processes now running
12:33:00.960 394250 Listening...
[...]
12:33:02.998 394360 search_tidyup called
12:33:02.998 394360 search_tidyup called
12:33:02.998 394360 >>>>>>>>>>>>>>>> Exim pid=394360 (daemon-accept-delivery) terminating with rc=0 >>>>>>>>>>>
12:33:03.063 394365 read response data: size=75
12:33:03.063 394365   SMTP<< 250 2.1.0 Ok
12:33:03.063 394365 sync_responses expect rcpt
12:33:03.063 394365   SMTP<< 250 2.1.5 Ok
12:33:03.063 394365   SMTP<< 250 2.0.0 Ok: 1376 bytes queued as EDDF2F5F5E
[...]
12:33:03.087 394364 DSN: Remote SMTP server supports DSN: 1
12:33:03.087 394364 DSN: not sending DSN success message
12:33:03.087 394364 LOG: MAIN
12:33:03.087 394364   Completed QT=0.385s
12:33:03.087 394364 end delivery of 1pY9HC-001eag-Me
12:33:03.087 394364 search_tidyup called
12:33:03.087 394364 search_tidyup called
12:33:03.088 394364 >>>>>>>>>>>>>>>> Exim pid=394364 (daemon-accept-delivery) terminating with rc=0 >>>>>>>>>>>
**Why a 4 seconds gap here?**
12:33:07.772 394366 DNS lookup of localhost (AAAA) gave HOST_NOT_FOUND
12:33:07.772 394366 returning DNS_NOMATCH
12:33:07.772 394366 faking res_search(AAAA) response length as 65535
12:33:07.772 394366  writing neg-cache entry for localhost-AAAA-800043, ttl 86400
12:33:07.773 394366 DNS lookup of localhost (A) gave HOST_NOT_FOUND
[...]
12:33:08.417 394438 DSN: Remote SMTP server supports DSN: 1
12:33:08.417 394438 DSN: not sending DSN success message
12:33:08.417 394438 LOG: MAIN
12:33:08.417 394438   Completed QT=0.343s
12:33:08.417 394438 end delivery of 1pY9HI-001ebt-2N
12:33:08.417 394438 search_tidyup called
12:33:08.417 394438 search_tidyup called
12:33:08.417 394438 >>>>>>>>>>>>>>>> Exim pid=394438 (daemon-accept-delivery) terminating with rc=0 >>>>>>>>>>>
**Another 4-5 seconds gap**
12:33:13.146 394440 DNS lookup of ip6-localhost (AAAA) gave HOST_NOT_FOUND
12:33:13.146 394440 returning DNS_NOMATCH

每條接受和發送的訊息都會DNS lookup of localhost gave HOST_NOT_FOUND返回,因此可能不是導致問題的原因。

隨著處理的郵件數量的增加,電子郵件之間的間隙變得越來越頻繁。每個間隙所花費的時間也會延長。最終出現超時。

這是 Perl 程式碼的摘要。請注意,實際程式碼更複雜,有許多類別和子類,但其要點是:

# Create SMTP server
$smtp_transport = Email::Sender::Transport::SMTP->new( $params );
my $unsent_messages = get_unsent_messages( $messages_args );

foreach my $message ( @$unsent_messages ) {
    # Create email and assign args
    my $email = Email::Stuffer->new();
    $email->to( $message->{to} );
    # [...] other arguments, headers, etc.
    $email->send_or_die( transport => $smtp_transport );
}

可能是什麼原因導致這個問題。我該如何調試並找出問題出在哪裡?該配置與我們在其他伺服器上的配置完全相同,它可以在不到一分鐘的時間內處理數百封電子郵件,因此我懷疑這是一個配置設定。可能是硬體差異嗎?

使用 Exim 版本 4.94.2 #2 於 2021 年 7 月 13 日 16:04:57 構建,Postfix mail_version = 3.4.23。

更新

一個簡單的 for 迴圈(見下文)以閃電般的速度發送訊息,沒有延遲。所以問題似乎出在 Perl 上。

for f in {1..111}; do mail -s TestDeCourriel [email protected] <<< "Mail content"; done

第二次更新

使用 s-nail 連接到本機 SMTP 伺服器而不是使用 mail / sendmail 的相同循環可以重現問題。

for i in {1..111}; do echo "This is a test message. $(date)" | s-nail -S mta=smtp://localhost:25 -s "Some s-nail mail" [email protected]; done

相關內容