如果你使用过 postfix 服务器,就知道外发邮件的瓶颈不是服务器硬件本身,而是外部邮件服务器接受邮件的速率。
为了充分利用闲置资源,我们可以给服务器增加一个或多个IP地址,利用Postfix的多进程功能来增加一个或多个Postfix进程。这样,就可以让服务器的邮件发送量翻倍。
准备工作
1. 首先,给主机增加一个IP地址。
2. 确认 Postfix 服务器正常运行。
3. 启用 Postfix 的多进程支持,执行命令:
postmulti -e init
4. 创建一个新的Postfix进程:
postmulti -I postfix-2 -G outgoing -e create
-I 是进程的名字,可以使用主机名或其它名字。
-G 是组的名字,本帖子没有用到组所以随便起个名字。如果想同时重启某几个进程时可用到组。
上面的创建新进程的命令,会生成用于保存配置文件和邮件队列的目录。目录结构很简单但很重要,因为后面使用进程时会需要用到:
配置文件例如 main.cf 文件位于 /etc/instancename/,以前面的新进程为例,目录是 /etc/postfix-2/
邮件队列位于 /var/spool/instancename/,以前面的新进程为例,目录是 /var/spool/postfix-2/
5. 给 Postfix 进程绑定IP地址
假设我们有两个 IP 地址 – 192.168.50.44 192.168.50.45
系统默认的进程的配置文件位于目录 /etc/postfix, 我们保留原来的 localhost, 并绑定特定的地址 192.168.50.44:
修改文件 /etc/postfix/main.cf,找到:
inet_interfaces = all
修改为:
inet_interfaces = localhost, 192.168.50.44
打开文件 /etc/postfix/master.cf, 找到:
smtp unix - - n - - smtp
修改为:
smtp unix - - n - - smtp -o smtp_bind_address=192.168.50.44
也就是默认的 Postfix 进程将通过 192.168.50.44 发送邮件。
对其它的每个进程,修改相应的 /etc/instancename 目录下的 main.cf 配置文件,来绑定各自的 IP 地址。
对我们上面的例子,就是修改文件 /etc/postfix-2/main.cf,找到:
inet_interfaces = all
修改为:
inet_interfaces = 192.168.50.45
打开文件 /etc/postfix-2/master.cf, 找到:
smtp unix - - n - - smtp
修改为:
smtp unix - - n - - smtp -o smtp_bind_address=192.168.50.45
6. 重启 postfix 服务使前面的修改生效
7. 安装一个或者多个 phplist
8. 配置每个 phplist 从不同的 postfix 进程发出邮件
以前面的postfix新进程为例,在 phplist 的文件 admin/index.php 的前面加上下面的代码:
putenv("MAIL_CONFIG=/etc/postfix-2");
(说明: 如果只想安装一个phplist,那么 “postfix-2” 可以使用变量)
9. 最后需要将运行 phplist 用户的名字加入 /etc/postfix-2/main.cf 的允许发送邮件的用户列表
authorized_submit_users = testuser
10. (供参考) 下面是用于 启动/停止/启用/禁用 postfix 进程的命令:
postmulti -i postfix-2 -p start
postmulti -i postfix-2 -p stop
postmulti -i postfix-2 -e enable
postmulti -i postfix-2 -e disable
现在,我们可以同时运行多个 phplist 的计划任务,同一台邮件服务器的邮件发送量就翻倍了。
GREAT !!!!!!!!!
Many Thanks !!!!
Hi!
Thanks for your tutorial. Really good work! But what i would like to know is, how do you handle bounces when you have setup different instances of postfix?
Thanks in advance,
Peter
You can setup the mailbox for the bounces in config.php:
# Message envelope.
#
# This is the address that most bounces will be delivered to
# Your should make this an address that no PERSON reads
# but a mailbox that phpList can empty every so often, to process the bounces
$message_envelope = ‘bounces@mydomain.com’;
# Handling bounces. Check README.bounces for more info
# This can be ‘pop’ or ‘mbox’
$bounce_protocol = ‘pop’;
# set this to 0, if you set up a cron to download bounces regularly by using the
# commandline option. If this is 0, users cannot run the page from the web
# frontend. Read README.commandline to find out how to set it up on the
# commandline
define (“MANUALLY_PROCESS_BOUNCES”,1);
# when the protocol is pop, specify these three
$bounce_mailbox_host = ‘smtp.mydomain.com’;
$bounce_mailbox_user = ‘bounces’;
$bounce_mailbox_password = ‘mypassword’;
Hi again!
The Problem i got is, that the sending instance has its own domain (abc.com). So bounces@abc.com will be delivered to the mx of this domain. The postfix instance is refusing smtp connections at this time. So what i wanted was, an postfix instance that is sending and recieving mail for one domain.
Regards,
Peter
Thank you for this helpful post but when i put putenv(“MAIL_CONFIG=/etc/postfix-2”); at the first line in phpList, it does not send any thing and it told me failure to send when i try to send a test email throught phpList.
Please help me
1. make sure you start the postfix instance:
postmulti -i postfix-2 -p start
2. the beginning of the file /admin/index.php should be something like:
Note: The quotation marks sometime get changed when you copy from the blog.
Dear Sir
I hope to start e mail marketing business . I have around more than 200,000 email address with me. I hope Purchase domain from hostgator and vps from hostgator with few extra IP. After that I i hope to update Name server as well as A record and MX record . I hope to setup few postfix instance with one phplist.Please let me know briefly how can achieve this.
I would say setup one phplist and postfix first. If it works then follow the steps in this post.
Dear Jack Huang
I setup PHP List on VPS it’s working fine.That VPS I purchased with extra 5 Public IP for balance outgoing e-mails via multiple IP .The solution is depending on postfix`s TCP_TABLES and a perl script..
Install the perl module List::util::WeightedRoundRobin:
cpan install /List::util::WeightedRoundRobin/
Create the following perl script and make it executable:
vi /etc/postfix/random.pl
#!/usr/bin/perl -w
# author: Hari Hendaryanto
use strict;
use warnings;
use Sys::Syslog qw(:DEFAULT setlogsock);
use List::Util::WeightedRoundRobin;
use Storable;
my $hashfile=”/tmp/file.hash”;
store {}, $hashfile unless -r $hashfile;
#
# our transports lists, we will define this in master.cf as transport services
# Queued using Weighted Round-Robin Scheduling
#
my $list = [
{
name => ‘smtp1:’,
weight => 1,
},
{
name => ‘smtp2:’,
weight => 1,
},
{
name => ‘smtp3:’,
weight => 1,
},
{
name => ‘smtp4:’,
weight => 1,
},
{
name => ‘smtp5:’,
weight => 1,
},
{
name => ‘smtp6:’,
weight => 1,
},
{
name => ‘smtp7:’,
weight => 1,
},
];
my $WeightedList = List::Util::WeightedRoundRobin->new();
my $weighted_list = $WeightedList->create_weighted_list( $list );
# $maxinqueue max number of queue in smtp list
my $maxinqueue = scalar(@{$weighted_list});
#
# Initalize and open syslog.
#
openlog(‘postfix/randomizer’,’pid’,’mail’);
#
# Autoflush standard output.
#
select STDOUT; $|++;
while () {
chomp;
my $count;
my $hash=retrieve($hashfile);
if (!defined $hash->{“index”})
{
$count = 0;
} else {
$count = $hash->{“index”};
}
if ($count >= $maxinqueue)
{
$hash->{“index”} = 0;
$count = 0;
}
$hash->{“index”}++;
store $hash, $hashfile;
my $random_smtp = ${$weighted_list}[$count];
if (/^get\s(.+)$/i) {
print “200 $random_smtp\n”;
syslog(“info”,”Using: %s Transport Service”, $random_smtp);
next;
}
print “200 smtp:\n”;
}
Execute the script to make sure it`s working and no errors are encountered:
/etc/postfix/random.pl
Configure postfix to use the random generated smtp transport.
Edit /etc/postfix/master.cf, by appending following lines:
## Round-robin outgoing smtp
127.0.0.1:23000 inet n n n – 0 spawn
user=nobody argv=/etc/postfix/random.pl
# random smtp
smtp1 unix – – n – – smtp
-o syslog_name=postfix-smtp1
-o smtp_helo_name=FQDN
-o smtp_bind_address=IP
smtp2 unix – – n – – smtp
-o syslog_name=postfix-smtp2
-o smtp_helo_name= FQDN
-o smtp_bind_address=IP
smtp3 unix – – n – – smtp
-o syslog_name=postfix-smtp3
-o smtp_helo_name=FQDN
-o smtp_bind_address=IP
smtp4 unix – – n – – smtp
-o syslog_name=postfix-smtp4
-o smtp_helo_name=FQDN
-o smtp_bind_address=IP
smtp5 unix – – n – – smtp
-o syslog_name=postfix-smtp5
-o smtp_helo_name=FQDN
-o smtp_bind_address=IP
smtp6 unix – – n – – smtp
-o syslog_name=postfix-smtp6
-o smtp_helo_name= FQDN
-o smtp_bind_address=IP
smtp7 unix – – n – – smtp
-o syslog_name=postfix-smtp7
-o smtp_helo_name= FQDN
-o smtp_bind_address=IP
Replace FQDN with desired hostname and IP with the list of the IP addresses you`d like to use.
Append the following lines to your /etc/postfix/main.cf:
transport_maps = tcp:127.0.0.1:23000
127.0.0.1:23000_time_limit = 3600s
Restart/reload postfix and verify everything is working correctly:
# postmap -q “dummy” tcp:127.0.0.1:23000
smtp4:
# postmap -q “dummy” tcp:127.0.0.1:23000
smtp5:
# postmap -q “dummy” tcp:127.0.0.1:23000
smtp6:
In your logs you should see the different smtp transport beeing used when mails are sent:
Sep 2 12:50:05 myserver postfix-smtp2/smtp[2016]: 3CA964C0004: to=, relay=domain.org[XXXXXXXXX]:25, delay=2, delays=0.03/0.01/0.18/1.8, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005tU-E9)
Sep 2 12:50:05 myserver postfix-smtp5/smtp[2014]: 4EE244C0012: to=, relay=domain.org[XXXXXXXXX]:25, delay=2, delays=0.01/0/0.21/1.8, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005tx-Gn)
Sep 2 12:50:05 myserver postfix-smtp3/smtp[2045]: 69305680035: to=, relay=domain.org[XXXXXXXXX]:25, delay=2, delays=0.05/0/0.11/1.9, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005uJ-Ih)
Sep 2 12:50:05 myserver postfix-smtp3/smtp[2034]: 444B94C0006: to=, relay=domain.org[XXXXXXXXX]:25, delay=2.2, delays=0.04/0/0.21/1.9, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005tW-G9)
Sep 2 12:50:05 myserver postfix-smtp1/smtp[2039]: 585A6583CFE: to=, relay=domain.org[XXXXXXXXX]:25, delay=2.2, delays=0.01/0/0.15/2, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005u0-GO)
And also you get an entry when the perl script is used to provide transport:
Sep 2 13:24:59 myserver postfix/randomizer[2076]: Using: smtp6: Transport Service
Please advice me this setup Is OK for me or I need to send mails via multiple instance.
Hello Mr. Jack Huang
With this configuration I can get PHPList send emails for the 2 instances at once?
If so, what should I do to send for 3 instances at once
You can repeat these steps and create multiple instances.
Pingback:[LINK] – Configure phplist to send email from multiple postfix instances / IP addresses | Andrea C.
Hello. Is possibile tu use POSTFIX Multi-Istances with Client Software? I’m using Multi-Istances with Phplist and it work because Phplist use ( putenv(“MAIL_CONFIG=/etc/postfix-2”); …but with Client Software (Like Thunderbid, Outlook, ecc.)….Postfix use always the primary server’s IP and not the dedicate instance IP. There’s a Way?
PMTA is a better choice for this.
https://www.huangzhong.ca/install-and-config-powermta-pmta/
Hi , Thanks for your configuration .
I have an query
i have test your config in two ways
way 1 >>
putenv(“MAIL_CONFIG=/etc/postfix-2”); in index and seen in mail log . It shows all the que are gng through postfix-2
way 2>>
i removed putenv(“MAIL_CONFIG=/etc/postfix-2”); frm index and seen in mail log. It shows all the que are gng through postfix .
Now my question is that is it balancing que load on both the instances on each instance for one phplist ???
.
Actually i want to setup bulk email server using phplist.
i just want to process the que very fast with help of postfix instance . can u help me in this
You can update MAIL_CONFIG to select a different queue before the mail() function.
php mail() function seems to be in the file admin/phpmailer/class.phpmailer.php; see the function MailSend().