Postfix的郵件隊(duì)列管理
Postfix郵件隊(duì)列管理單元的服務(wù)器程序--qmgr,是整個(gè)postfix系統(tǒng)的中心樞紐。所有郵件,包括等待送出與從外界收進(jìn)來(lái)的,都必須通過(guò)Postfix郵件隊(duì)列。了解Postfix郵件隊(duì)列的運(yùn)行原理以及postfix如何處理Postfix郵件隊(duì)列,有助于你解決問(wèn)題。
Postfix郵件隊(duì)列管理器總共設(shè)置了五個(gè)做不同用途的Postfix郵件隊(duì)列,包括:輸入、活動(dòng)、等待、故障、保留。每個(gè)Postfix郵件隊(duì)列在queue_directory參數(shù)指定的路徑下各有一個(gè)專屬的子目錄。默認(rèn)的Postfix郵件隊(duì)列目錄是/var/spool/postfix/。
于后臺(tái)運(yùn)作的qmgr daemon能自動(dòng)處理大部分的Postfix郵件隊(duì)列管理工作,必要時(shí),管理員可使用postsuper和postqueue自己動(dòng)手管理。本章介紹qmgr于相關(guān)命令行工具的運(yùn)行原理,以及能影響Postfix郵件隊(duì)列的postfix參數(shù)。
qmgr的運(yùn)行原理
郵件進(jìn)入postfix系統(tǒng)的第一站是“輸入Postfix郵件隊(duì)列”。postfix以queue_minfree參數(shù)來(lái)保護(hù)Postfix郵件隊(duì)列文件系統(tǒng),此參數(shù)的默認(rèn)值為0,表示qmgr可以無(wú)限制地使用Postfix郵件隊(duì)列磁盤空間。如果你不想Postfix郵件隊(duì)列耗盡服務(wù)器地磁盤空間,建議你設(shè)定一個(gè)合理地上限值。
每當(dāng)有新信進(jìn)入收件Postfix郵件隊(duì)列,qmgr便會(huì)將郵件移到活動(dòng)Postfix郵件隊(duì)列,并調(diào)用適當(dāng)?shù)豈DA來(lái)處理。只要投遞過(guò)程沒(méi)遇到意外,這段流程通常是相當(dāng)迅速地,快到你沒(méi)機(jī)會(huì) 見(jiàn)到郵件停留在活動(dòng)Postfix郵件隊(duì)列里,除非postfix正在將郵件送到一臺(tái)非常慢地遠(yuǎn)程smtp server。如果無(wú)法在30秒內(nèi)連接到遠(yuǎn)程系統(tǒng),postfix便會(huì)認(rèn)為該系統(tǒng)目前無(wú)法到達(dá)。
暫時(shí)無(wú)法送出去地郵件會(huì)被放在等待Postfix郵件隊(duì)列??赡馨l(fā)生了臨時(shí)性意外包括:DNS系統(tǒng)暫時(shí)離線、遠(yuǎn)程服務(wù)器主機(jī)臨時(shí)故障、網(wǎng)絡(luò)不穩(wěn)定、收件人地郵箱爆滿等。如果遇到永久性地問(wèn)題或是被遠(yuǎn)程拒收,則郵件會(huì)連同錯(cuò)誤報(bào)告立刻被退回給原寄件人,不會(huì)留在Postfix郵件隊(duì)列里。
等待郵件
留在等待Postfix郵件隊(duì)列里地郵件,會(huì)待到它們被成功投遞出去,或因?yàn)槌瑫r(shí)而被退回給原寄件人為止。退信通知函與遭退郵件地總和大小不得超過(guò)bounce_size_limit,如果超過(guò)此限制,則原寄件人只會(huì)收到退信通知函,而不會(huì)收到遭退郵件本身。
如果郵件一時(shí)無(wú)法投遞,postfix會(huì)給郵件標(biāo)上一個(gè)時(shí)間,這個(gè)時(shí)間代表下次嘗試投遞得時(shí)刻。對(duì)于一時(shí)無(wú)法聯(lián)系得遠(yuǎn)程主機(jī),postfix會(huì)將它們另外 記錄在自己內(nèi)部得一份有時(shí)效性得名單上,借此避免不必要的遞送嘗試。如果有任何等待郵件要被安排重新投遞,而且活動(dòng)Postfix郵件隊(duì)列里有足夠空間,則qmgr會(huì)交替在 等待Postfix郵件隊(duì)列與收件Postfix郵件隊(duì)列之間取信。如此一來(lái),新進(jìn)郵件不至于因?yàn)閜ostfix正在忙著處理大量等待郵件而等待太久。
Postfix郵件隊(duì)列調(diào)度
postfix會(huì)定期掃描Postfix郵件隊(duì)列,檢查每一封等待郵件的時(shí)間,看看是否有任何等待郵件已經(jīng)到了下一回合應(yīng)該嘗試投遞的時(shí)間。每一次投遞失敗,都會(huì)導(dǎo)致延遲間 隔時(shí)間加長(zhǎng),所以,失敗次數(shù)越多,就必須等待更長(zhǎng)的時(shí)間才有再次被投遞的機(jī)會(huì)。延遲時(shí)間上限由maximal_queue_lifetime參數(shù)決定。如 果郵件在等待Postfix郵件隊(duì)列里的時(shí)間超過(guò)此上線,postfix便會(huì)放棄投遞,并退信給原寄件人。maximal_queue_lifetime的默認(rèn)值為5天,你 可以將它改成任何時(shí)間長(zhǎng)度;如果你希望postfix在第一次遞送失敗時(shí)就立刻退信,你可將此參數(shù)的值該為0。
postfix內(nèi)部的Postfix郵件隊(duì)列掃描間隔決定于queue_run_delay參數(shù),其默認(rèn)值為1000秒。也就是說(shuō),大約每隔1000秒,postfix就會(huì)檢查一次等待Postfix郵件隊(duì)列,看看是否有任何應(yīng)該再次嘗試投體的郵件。
postfix重新投體等待郵件的頻繁程度的上下限,分別由minimal_backoff_time與maximal_backoff_time這兩個(gè) 參數(shù)決定。每次郵件被延遲,qmgr便會(huì)加長(zhǎng)下次投遞機(jī)會(huì)的時(shí)間間隔,但是累增后的間隔時(shí)間不的超過(guò)上線,也不得低于下限。如果你發(fā)現(xiàn)經(jīng)常有寄不出去的等 待郵件,或許你應(yīng)該考慮適度加大上線,讓postfix不要浪費(fèi)太多資源于等待郵件。
投遞操作
每當(dāng)需要投遞郵件時(shí),qmgr便會(huì)調(diào)用適當(dāng)?shù)腗DA來(lái)運(yùn)行投遞程序。postfix會(huì)很謹(jǐn)慎地避免干擾收信系統(tǒng),并提供幾個(gè)參數(shù)來(lái)控制外寄郵件地可用資 源。這些參數(shù)地默認(rèn)值應(yīng)該足以應(yīng)付大部分地情況,但是如果你地操作環(huán)境特殊,需要調(diào)整資源分配或是想要改善投遞操作,你應(yīng)要實(shí)際的測(cè)試qmgr或MDA的 操作參數(shù),并依據(jù)實(shí)測(cè)效果來(lái)嫁衣調(diào)整。
列在master.cf配置文件里的各個(gè)MDA,都有可能被用來(lái)投遞外寄郵件。master.cf配置文件的maxproc字段限定了MDA的進(jìn)程數(shù)上限。如果該字段沒(méi)有明確的設(shè)定值,則postfix使用default_process_limit參數(shù)的值為默認(rèn)值。
大部分的MDA都有能力同時(shí)投遞多封郵件到同一個(gè)目的地,但是并非所有收信系統(tǒng)都時(shí)時(shí)刻刻有能力同時(shí)收下許多郵件。為了兼顧投遞效率于接收系統(tǒng)的工作負(fù) 荷,postfix使用一種特殊的投遞調(diào)度算法:如果有多封郵件要送到同一個(gè)目的地,MDA第一次最多只能同時(shí)送出 initial_destination_concurrency封郵件,如果能成功完成初次投遞,則postfix會(huì)嘗試同時(shí)送出更多郵件,知道發(fā)現(xiàn)目 的地系統(tǒng)不能承當(dāng)當(dāng)前的工作負(fù)荷,或是同時(shí)投遞的郵件數(shù)即將超過(guò)default_destination_concurrency_limit。
里可以適度提升initial_destination_concurrency參數(shù)的值,但是不能超過(guò)該MDA在master.cf配置文件的 maxproc字段值。一般而言,你不應(yīng)該提升default_destination_concurrency_limit,因?yàn)檫@有使收信系統(tǒng)癱瘓的 風(fēng)險(xiǎn)。
postfix隨附的每一個(gè)MDA,都有一個(gè)對(duì)應(yīng)的mad_destination_concurrency_limit參數(shù),它們的效力高于 default_destination_concurrency_limit參數(shù)。因此,如果想提升本地郵件的同時(shí)投遞量,而不想影響其他MDA,你可 以修改local_destination_concurrency_limit參數(shù)的值。同理,如果只想降低遠(yuǎn)程郵件的同時(shí)投遞量,而不影響其他 MAD,也可借由修改smtp_destination_concurrency_limit參數(shù)來(lái)達(dá)成目的。
同理,postfix內(nèi)置的所有MDA都有自己的mad_destination_concurrency_limit參數(shù),它們限制postfix將郵 件交給MDA時(shí),每次最多可以指定多少位收件人。如果同一封郵件的郵件人數(shù)超過(guò)MDA每次能夠承受的人數(shù),postfix會(huì)將收件人分成多個(gè)小組,分批投 遞。
損毀郵件
故障Postfix郵件隊(duì)列純粹用于存放受損或無(wú)法解讀的郵件。如果郵件已經(jīng)損壞到無(wú)法進(jìn)行任何處理的程度,postfix便將它們放在此處,供你調(diào)查故障原因。管理員可使 用“Postfix郵件隊(duì)列管理工具”提到的工具來(lái)檢查故障郵件。一般而言,故障郵件非常少見(jiàn),如果不幸遇到,通常是操作系統(tǒng)或硬件故障的征兆。
錯(cuò)誤通知函
postfix可發(fā)出“錯(cuò)誤通知函”給管理員,讓管理員知道發(fā)生了什么類型的錯(cuò)誤。postfix將錯(cuò)誤通知分成七大類,管理員可設(shè)定main.cf里的 notify_classes參數(shù)來(lái)決定要收哪些類型的錯(cuò)誤通知。在默認(rèn)情況下,管理員只會(huì)收到resource與software兩種錯(cuò)誤類型的通知 函。
對(duì)于每一種類型的錯(cuò)誤通知函,都有一個(gè)對(duì)應(yīng)的class_notice_recipient參數(shù),這些參數(shù)代表該類通知函的收件人地址,它們的默認(rèn)值都是postmaster。
bounce 遭退郵件本身的標(biāo)頭
2bounce 無(wú)法投遞的退信通知函
delay 被延遲郵件的標(biāo)頭
policy smtp對(duì)話過(guò)程(因違反垃圾郵件過(guò)濾條件而予以拒收的郵件)
protocol smtp對(duì)話過(guò)程(曾經(jīng)在smtp對(duì)話過(guò)程出現(xiàn)錯(cuò)誤者)
resource 因?yàn)橄到y(tǒng)資源問(wèn)題而投遞失敗的通知
software 因?yàn)檐浖?wèn)題而投遞失敗的通知
如果想收到所有問(wèn)題的通知函,請(qǐng)照下面這樣設(shè)定notify_classes參數(shù)
notify_classes = bounce, 2bounce, delay, policy, protocol, resource, software
如果你的站點(diǎn)有專人研究垃圾郵件,你可以這樣設(shè)定:
policy_notice_recipient = antispamexpert@example.com
Postfix郵件隊(duì)列管理工具
postfix提供了一組命令行工具來(lái)檢查、控制、管理Postfix郵件隊(duì)列里的郵件,其中以postsuper和postqucuc這兩個(gè)工具最為重要。你可以對(duì)Postfix郵件隊(duì)列中的郵件進(jìn)行下列操作:
顯示郵件列表
刪除郵件
重新排隊(duì)
保留郵件
顯示郵件內(nèi)容
清空郵件
每一種操作都有對(duì)應(yīng)的命令。
顯示郵件列表
郵件列表的顯示項(xiàng)目,包括郵件在Postfix郵件隊(duì)列里的標(biāo)識(shí)符、大小、到達(dá)時(shí)間、寄件人地址、收件人地址。對(duì)于等待郵件,還會(huì)另外顯示等待原因。如果郵件是在活動(dòng)Postfix郵件隊(duì)列 里,其標(biāo)識(shí)符欄會(huì)加注一個(gè)星號(hào)(除非你的服務(wù)器很慢或是負(fù)荷沉重,否則應(yīng)該沒(méi)有機(jī)會(huì)見(jiàn)到星號(hào))。在保留Postfix郵件隊(duì)列里的郵件的郵件,其標(biāo)識(shí)符欄會(huì)加注一個(gè)感嘆號(hào)。 等待郵件不加注任何符號(hào)。
使用postqueue -p 命令可列出Postfix郵件隊(duì)列里的所有郵件,其效果如果sendmail包的mailq。當(dāng)安裝postfix時(shí),安裝腳步會(huì)以postfix版的mailq程序(它其 實(shí)只是postqueue -p的符號(hào)鏈接而已)取代sendmail包原有的同名程序,借此維持與sendmail包的兼容性。
刪除郵件
使用postsuper命令的-d選項(xiàng),可移除Postfix郵件隊(duì)列里的郵件。郵件是以它們?cè)赑ostfix郵件隊(duì)列里的標(biāo)識(shí)符表示。
如果要?jiǎng)h除所有郵件,請(qǐng)把標(biāo)識(shí)符換成ALL
請(qǐng)注意,由于刪除所有郵件是相當(dāng)危險(xiǎn)的操作,所以ALL關(guān)鍵字必須全以大寫字母表示才有效,其目的是希望你三思而后行。
保留郵件
當(dāng)你想將郵件無(wú)限期留在Postfix郵件隊(duì)列系統(tǒng)里,保留Postfix郵件隊(duì)列就成為容納這些郵件的場(chǎng)所。不管郵件目前已經(jīng)傳到哪一個(gè)Postfix郵件隊(duì)列,你都可以將它們移除原來(lái)的Postfix郵件隊(duì)列,轉(zhuǎn)移到保留Postfix郵件隊(duì)列。
假設(shè)你已經(jīng)知道要保留的郵件的標(biāo)識(shí)符,使用postsuper工具的-h選項(xiàng),就可將指定的郵件搬到保留Postfix郵件隊(duì)列:
postsuper -h DRA3P1A9
在這之后,如果觀察郵件列表,會(huì)發(fā)現(xiàn)該郵件的標(biāo)識(shí)符多了一個(gè)感嘆號(hào)。
要將郵件移回原來(lái)的Postfix郵件隊(duì)列,繼續(xù)其未竟之進(jìn)程,可使用同一個(gè)postsuper工具,只要將原來(lái)的-h改成-H。
在郵件被移回原來(lái)的Postfix郵件隊(duì)列之后,qmgr依照平常的調(diào)度原則來(lái)決定其下次投遞時(shí)間。或者,你也可以執(zhí)行清空(flush)命令,立刻將郵件遞送出去。
重新排隊(duì)
如果因?yàn)榕渲脝?wèn)題而耽誤了任何郵件,在問(wèn)題解決之后,你可能希望被耽擱的郵件重新走一遍Postfix郵件隊(duì)列處理流程,以便能夠成功完成遞送。因?yàn)榕渲脝?wèn)題可能使得 postfix在郵件里存儲(chǔ)了錯(cuò)誤的投遞處理信息,或是使用了錯(cuò)誤的地址改寫法則。重新排隊(duì)會(huì)使得postfix依據(jù)里的新配置來(lái)修正錯(cuò)誤信息。使用 postsuper工具的-r選項(xiàng),可以重新排隊(duì)某一特定郵件,或是要求所有郵件全部都重新排隊(duì)。
顯示郵件內(nèi)容
使用postcat工具的-q選項(xiàng),可以查看一個(gè)Postfix郵件隊(duì)列文件的內(nèi)容
早期版本的postcat并未提供-q選項(xiàng),而是要求你提供Postfix郵件隊(duì)列文件的完整路徑。然而,由于郵件可能在各個(gè)Postfix郵件隊(duì)列目錄之間游移不定,而且這些Postfix郵件隊(duì)列目錄還有自己的子目錄,所以管理員很難一眼看出Postfix郵件隊(duì)列文件的完整路徑。
清空郵件
要求postfix立刻投遞滯留在Postfix郵件隊(duì)列里的郵件的操作稱為清空(flush),執(zhí)行清空動(dòng)作的命令是postqueue -f。不過(guò),除了你有理由確定郵件一定能成功投遞出去,否則,最好還是讓qmgr自己決定重新投遞的時(shí)機(jī)。不斷的反復(fù)要求清空,會(huì)嚴(yán)重影響郵件服務(wù)器的效 率。
使用-s選項(xiàng)可清空寄到特定站點(diǎn)的郵件,而且收件站點(diǎn)必須要有接收快速清空的“資格”才有效。要使得某站點(diǎn)具備此資格,你必須將該站點(diǎn)的主機(jī)名稱或網(wǎng)域名 稱列在fast_flush_domains參數(shù)中。此參數(shù)的默認(rèn)值只包含relay_domains所列的所有網(wǎng)域,但是你可以視情況增加額外的站點(diǎn):
fast_flush_domains = $relay_domains example.com
如果你有一個(gè)間歇性的郵件交換機(jī),你可以在該交換器上線的時(shí)間內(nèi),使用postqueue -s清空先前無(wú)法送達(dá)到該交換器的所有郵件:
postqueue -s example.com
【編輯推薦】