そろそろ腐りそうな知見なので、腐りきる前にメモだけ残しておく。
まあ、基本的にはSendGridなどのクラウドサービスを使った方がいいと思うけど、どこかの誰かの役に立つかもしれないので…
Postfixでメール配信の流量制限を行う場合、送る量を制限するか、MTAに入ってくる量を制限するかの2通りの方法があると思う。
送る量を制限しようと思うとslow_destination_rate_delay=1s
みたいな設定値を追加して、送信毎に遅延をかけるような感じになると思う。
しかし、この方法だと1s以下に設定することができないので、毎分何万通も送るようなシステムだと極端に配信量が下がってしまう。 また、流量制限を行う場合は単に遅延を設けるだけでなく「毎分xxx通」といった厳密な指定がしたい。
そこで、MTAに入ってくる量を制限する。
単純にMTAに入ってくる量を制限すると、上限超えたときにクライアントでエラーが出る。 なので、以下のようにPostfixを2段構成にする。
インターネットに面したPostfixでは、master.cfで送信先毎の流量を設定する
11125 inet n - n - - smtpd -o syslog_name=postfix/gmail -o smtp_destination_concurrency_limit=1 -o smtp_destination_recipient_limit=1 -o smtpd_client_message_rate_limit=1000 11126 inet n - n - - smtpd -o syslog_name=postfix/docomo -o smtp_destination_concurrency_limit=1 -o smtp_destination_recipient_limit=1 -o smtpd_client_message_rate_limit=400
クライアントに面したPostfixでは流量制限したい宛先のポートをtransportで変更する。
gmail.com smtp:[outside-load-balancer]:11125 docomo.ne.jp smtp:[outside-load-balancer]:11126
また、main.cfで再送間隔を短くしておく。
minimal_backoff_time = 3m maximal_backoff_time = 15m queue_run_delay = 3m
こういう構成にしておくと、gmail宛には1000通/分、docomo宛には400通/分、みたいな感じで流量を制限することができる。
経験上、3キャリアとGMailについては流量に制限をかけておいた方が無難だと思う…
またこの構成でのもう一つのメリットは、流量制限によってメールが溜まるキューがインターネット側のPostfixではなく、クライアント側のPostfixであるという点だ。 インターネット側のPostfixはたぶんグローバルIPを持つことになると思うが、特定のIP のPostfixのキューにメールが溜まってしまうと、そのIPが大量配信などで受け取り拒否されたときに困ったことになってしまう。 クライアント側のキューの方にメールが溜まっている状態なら、流量制限のリミットの引っかかった場合、再送でロードバランサーが別のPostfixに適度に振り分けてくれる。