You may try below haproxy configuration to achieve load-balancing of incoming SMTP connections.
timeout http-request 10s
timeout http-keep-alive 10s
timeout check 10s
timeout server 10s
timeout connect 10s
timeout client 10s
stats uri /stats
stats auth admin:admin@123
no option http-server-close
option smtpchk HELO mail.example.org ##mail.example.org is the domain name presented to the server. By default localhost is used.
default-server inter 10000 fall 1 rise 2 downinter 1000
server mailserver1 xxx.xxx.xxx.xxx:25 send-proxy check
server mailserver2 yyy.yyy.yyy.yyy:25 send-proxy check
To summarize the set-up, I have two mail servers mailserver1 and mailserver2. Health of both the mail servers are periodically checked using smtpchk keyword which consist of creating a TCP connection followed by issuing an SMTP command. The server’s return code is then analysed to infer its health.
Also, very often the backend mail servers require the client IP to perform various operations such as spam filtering and anti-spoofing on incoming mails. Therefore, we used send-proxy keyword so that HAProxy ensures that the client IP is forwarded to backend servers.
Other keywords used are:
inter : Interval between 2 consecutive health checks.
fall : The number of consecutive health check failures after which a server would be marked as DOWN.
rise : The number of consecutive health check successes after which a server which was previously DOWN would be marked as UP.
downinter: The interval between 2 consecutive health checks when a server is in DOWN state.
WORST CASE SCENARIO:
HAProxy performed a check at 00:00:00 GMT and both the mail servers were found to be UP. The next health check would therefore be performed at 00:00:10 GMT. However, just after the first successful health check, mailserver1 started crashing and at that very moment, coincidentally, an email arrived and HAProxy forwarded that email to mailserver1. What would be the fate of that email?
As per above configuration, if an incoming mail is forwarded to a deteriorating mail server, mailserver1 in this case, and the connection request to that mail server fails then 3 retires are performed at an interval of 10 seconds each (timeout connect 10s). Also, since redispatch is enabled, the last retry would be performed on a different server which is in good health. Therefore, the chances of a mail getting discarded due to a bad server are quite bleak.
Hope this is helpful !