Shell-Script

通過使 cronjob 每秒執行來處理 Postfix 郵箱中的多封郵件——這被認為是好的做法嗎?

  • March 9, 2019

我需要每小時處理至少三千封在 postfix 郵箱中收到的電子郵件。處理包括提取電子郵件附件並將電子郵件附件的內容髮送到外部電子郵件地址。對於每個電子郵件附件,我都會發送一封電子郵件。我想我可以通過編寫一個腳本讓 cronjob 每秒休眠一次來實現這一點,但我不確定這是一個好的做法(這樣做很容易讓我每小時處理大約 3600 封郵件)。請就解決此問題的最佳方法提出建議。我已經有一個提取電子郵件和發送電子郵件的腳本,腳本的唯一問題是它一次只能處理一封電子郵件。如果我使用每分鐘 cronjob,我每小時只能處理 60 封郵件,而目標實際上是每小時至少 3000 封郵件。

Procmail 可以輕鬆解決這個問題,前提是您的伺服器有 CPU 和頻寬來維持流量。如果您已經有一個腳本來處理這個問題,只需將每條傳入消息通過管道傳輸到您的腳本。將以下內容放入您的$HOME/.procmailrc:

:0
| /path/to/your/script

腳本接收消息作為其標準輸入,並負責從這裡開始傳遞或以其他方式處理消息。(換句話說,Procmail 根本不會將此郵件發送到您的收件箱。請參閱下文了解如何修改此行為。)

(Procmail 並不是絕對必要的,但它添加了一個很好的安全網,因此您的腳本不需要處理所有可能的錯誤情況。.forward如果您的腳本足夠健壯,您可以簡單地將管道塞進您的。這是基本上@number5 的評論也告訴你什麼,除了它在 Postfix 的配置文件中執行此操作,而不是使用該.forward工具。)

如果腳本的兩個實例不能同時執行(例如,因為它需要對後端數據庫的獨占訪問),請添加鎖定文件:

:0:yourscript.lock
| /path/to/your/script

這將導致 Procmail 查找文件yourscript.lock,如果存在,則等待它消失;然後創建文件,執行配方,並刪除鎖定文件。

使用鎖定文件會強制對傳遞進行序列化。不過,這會降低性能。如果可能的話,最好使腳本在並行執行下健壯。

另一方面,如果您的腳本在伺服器上產生了沉重的負載,您可能不想執行多個並發實例;在這種情況下,如果您強制序列化傳遞,性能實際上可能會提高。

如果您還想在收件箱中獲得一份副本,請在發送到您的腳本時複製一份副本:

:0c # or :0c:yourscript.lock
| /path/to/your/script

您還可以添加一個條件,以便例如僅將具有特定主題行的消息通過管道傳輸到您的腳本。條件以星號作為第一個字元指定,後跟需要匹配消息標題的正則表達式。

:0
* ^Subject: xyzzy$
| /path/to/your/script

如果上述不合適,以下配方將提取所有附件到一個目錄並為每條傳入消息發送一封電子郵件。循環訪問附件可能最好從像上面這樣的外部腳本完成,但這至少應該讓您了解在 Procmail 本身中做更多的事情會是什麼樣子。

METAMAIL_TMPDIR=`mktemp -d /tmp/extracted.XXXXXXXXX`

# Crude attachment extraction ... how are you currently doing this?
:0c
| metamail -w -d

COUNT=`find "$METAMAIL_TMPDIR" -printf "%i\n" | wc -l`

:0
| ( echo Subject: $COUNT attachments extracted into $METAMAIL_TMPDIR; echo; echo ) \
 | sendmail -oi you@example.com

引用自:https://unix.stackexchange.com/questions/84218