Postfixのメールのキューが滞留して対処する必要があったのでメモ。
イベント
メールマガジンの配信を行っていたが、送信先の都合で滞留してしまった。
対処の流れ
- キューの状態を調べる
- 再配送を試みる→だめ
- キューをホルド(削除はしない。バウンスさせるのもあり)
- 報告書を書くためにキューの送信元送信先を調べる。
キューの実体ファイルのパス
# ls /var/spool/postfix/
active bounce corrupt defer deferred flush hold incoming maildrop pid private public saved trace
## キューの内容を確認する方法
正直パースしにくいので、使い道が限られる。より良い方法は後述
$ postqueue -p
--------------------
22E7C42D14 4075 Wed Jul 1 10:06:45 info@hoge.com
(delivery temporarily suspended: lost connection with hogehoge while sending end of data -- message may be sent more than once)
fugafuga@example.com
--------------------
キューの再配送を試す。
キューの再配送は自動で行われるが、だんだんと間隔が長くなるので、強制的に再配送を試したくなるので以下のようにする。
- キューを指定して送信する場合
$ postqueue -i ${queueId}
- 全部再配送
$ postqueue -f
キューをホルドする方法
deferredのみを固める場合は以下のようにする。
$ sudo postsuper -h ALL deferred
キューに入っているメールの内容を確認する方法
一応どんな内容のメールなのかをみておいたほうが良いだろう。
$ postcat -q ${queueId}
ex) $ postcat -q 22E7C42D14
キューの内容を確認する方法(2)
postqueue -pがパースしにくいので、postcatを使ったワンライナーを作成
$ for qid in $(ls /var/spool/postfix/hold/); do postcat -q $qid | grep '^sender: \|^recipient: ' | xargs echo -n; echo; done > /home/sci01436/holdedlist.txt
--------------------
sender: info@hoge.com recipient: fugafuga@example.com
--------------------
送信元と送信先を並べて出力できる。手軽。postqueue -pは不要だと思う。キューIDだけ返すコマンドにしたほうが良かったのでは?
監視
おまけ
以下の様なシェルをZabbix等から呼び出せば滞留したメールを検知できる。
#!/bin/bash
# postqueueからもっとも古いキューの到着日時を返す
# フォーマットエラー、ファイル不在などあれば-1を返す
function error(){
/bin/echo -1
exit 1
}
function queue_arrival_time(){
qid=$1
date -d "`/usr/sbin/postcat -q $qid | /bin/grep 'message_arrival_time:' | /bin/sed 's|^message_arrival_time: \(.*\)$|\1|g'`" '+%s'
}
now=$(/bin/date '+%s')
oldest_arrival_time=$now
qpaths=$(/bin/find /var/spool/postfix/deferred -type f) || error
for qpath in $qpaths
do
qid=`/bin/basename $qpath`
arrival_time=$(queue_arrival_time $qid) || error
if [ $arrival_time -lt $oldest_arrival_time ]; then
oldest_arrival_time=$arrival_time
fi
done
echo `/usr/bin/expr $now - $oldest_arrival_time`