[exim] Exim Performance / Server Performance

Top Page
Delete this message
Reply to this message
Author: RootChaos
Date:  
To: exim-users
Subject: [exim] Exim Performance / Server Performance
Hi Guys

I need some help with perhaps a general config tweak or perhaps some
completely new suggestions.

We have a mail server with the following configuration :-

Exim 4.30 (MySQL Database backend - Virtual Mailboxes)
Amavisd-new
F-PROT Antivirus
Spamassassin
Qpopper



Hardware Config :-

Dual Intel P4 2.8
2 GIG Ram
1 x 120 GIG IDE Hard Drive


Currently we have about 6000 mail boxes on the server. We seem to be running
into some very heavy queues of mail not being delivered to the mailboxes on
the local server. This starts at about 8am in the morning when mail seems to
be queued on the server, some of them for even up to 8 hours. As the day
comes to the end, at about 7PM, all the mail that queued for the day seems
to have been delivered to the mailboxes on the server which is causing a
problem for us not delivering mail on time as they come into the server.

We have been playing with adding amavis processes, but that didn't seem to
have done the trick as it puts additional loads on the server, causing the
server to take strain, sometimes reaching a load of over 20 with high IOWAIT
stats as well.

We have moved the amavisd-new, spamassassin and now ClamAV onto a totally
separate server which caused the load on the primary mail server to come
down to under 1, IOWAIT is also very low. The server seems to be idleing
along most of the times, however mail keeps on queueing on the server for
some reason. All new mails coming into the server gets processed
immediately, but those in the queue seems to be stuck till after the end of
day when they are processed and delivered.

The server running amavisd-new, spamassassin and ClamAV also has aload of
under 1 now, which to me sounds like we are heading in the right direction
having two servers doing the job. We currently have 12 amavisd processes
running on the server. ClamAV is configured as a socket on the server and it
seems like it's working pretty well, we just can't get rid of the queues....

We have quite a bit of tweaking in the exim config file, of which a copy is
included so that you might look at the config and perhaps send some
suggestions of what we are doing wrong.


Any suggestions are welcome !!!



Regards


RC
[root@mx01 root]# cat /etc/exim/exim4.conf

system_filter = /usr/local/etc/exim/sa

# SQL QUERIES
MYSQL_AUTH = SELECT domain FROM relays WHERE domain="${sender_host_address}" and relay_type="2"
MYSQL_RELAY = SELECT domain FROM relays WHERE domain="${sender_host_address}" and relay_type="2"

MYSQL_RELDOM = SELECT domain FROM relays WHERE domain = "$domain" and relay_type="3"
MYSQL_RELETRN = SELECT domain FROM relays WHERE domain = "$domain" and relay_type="1"
MYSQL_QDOMAINS = SELECT domain FROM relays WHERE domain = "$domain" and relay_type="3"
MYSQL_REJECT = SELECT domain FROM relays WHERE domain = "${sender_host_address}" and relay_type="4"

tls_advertise_hosts = *
tls_certificate = /usr/local/etc/ssl/smtp.crt
tls_privatekey = /usr/local/etc/ssl/smtp.key
tls_dhparam = /usr/local/etc/ssl/smtp.pem

#local_interfaces = 0.0.0.0.25 : 127.0.0.1.10025
local_interfaces = 0.0.0.0.25 : 10.0.0.8.10025 : 127.0.0.1.10025

# MYSQL SERVER
hide mysql_servers = 10.0.0.27/dbname/username/password

# SMTP BANNER
smtp_banner = SMTP

# EXIM CONFIG
primary_hostname = mx01.xxx.com
domainlist local_domains = ${lookup mysql{SELECT distinct domain FROM relays \
                                WHERE domain="$domain" AND relay_type="5" AND in_use="1" }}:smtp.xxx.com:mx01.xxx.com:mailman.xxx.com:mx02.xxx.com
domainlist relay_to_domains = ${lookup mysql{SELECT domain FROM relays \
                                WHERE domain="$domain"}}:mysql;MYSQL_RELETRN:mysql;MYSQL_RELDOM:mx02.xxx.com


hostlist relay_from_hosts = net-mysql;MYSQL_RELAY:net-mysql;MYSQL_AUTH:/usr/local/etc/exim/relays

queue_domains = mysql;MYSQL_RELETRN
# queue_domains = mysql;MYSQL_RELETRN:mysql;MYSQL_QDOMAINS
host_reject_connection = net-mysql;MYSQL_REJECT

trusted_users = web:root:exim

# MAX MESSAGE SIZE
message_size_limit = 10M
return_size_limit = 100K

# ETRN
smtp_etrn_command = "/usr/local/sbin/exim -R \
        \"${if match {$domain}{^[@#]}{${substr_1:$domain}}{$domain}}\""
smtp_etrn_serialize = false
# ACL Configuration
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_etrn = check_etrn
acl_smtp_data = acl_check_content


# EXIM USER
exim_user = root
exim_group = mail

# EXIM EXTRA CONFIGURATION - Performance stuff.
split_spool_directory

## The value of this option limits the number of MAIL commands that Exim is prepared to accept over a single SMTP connection, whether or not each command results in the transfer of a message
#smtp_accept_max_per_connection = 200
#smtp_accept_max_per_connection = 20
smtp_accept_max_per_connection = 100
##

## This option limits the number of delivery processes that Exim starts automatically when receiving messages via SMTP, whether via the daemon or by the use of -bs or -bS. If the value of the option is greater than zero, and the number of messages received in a single SMTP session exceeds this number, subsequent messages are placed on the queue, but no delivery processes are started
#smtp_accept_queue_per_connection = 25
smtp_accept_queue_per_connection = 100
##

## This option specifies a maximum number of waiting SMTP connections. Exim passes this value to the TCP/IP system when it sets up its listener. Once this number of connections are waiting for the daemon's attention, subsequent connection attempts are refused at the TCP/IP level
smtp_connect_backlog = 50
#smtp_connect_backlog = 150
##

## This option specifies the maximum number of simultaneous incoming SMTP calls that Exim will accept
smtp_accept_max = 1500
#smtp_accept_max = 300
##

## This option restricts the number of simultaneous IP connections from a single host (strictly, from a single IP address) to the Exim daemon
#smtp_accept_max_per_host = 100
smtp_accept_max_per_host = 25
##

## If the number of simultaneous incoming SMTP calls handled via the listening daemon exceeds this value, messages received by SMTP are just placed on the queue
#smtp_accept_queue = 70
smtp_accept_queue = 300
##

## If the system load average ever gets higher than this, incoming SMTP calls are accepted only from those hosts that match an entry in smtp_reserve_hosts.
smtp_load_reserve = 38
##

## When this option is set, a queue run is abandoned if the system load average becomes greater than the value of the option
#deliver_queue_load_max = 20
deliver_queue_load_max = 30
##

## This controls the maximum number of queue runner processes that an Exim daemon can run simultaneously. This does not mean that it starts them all at once, but rather that if the maximum number are still running when the time comes to start another one, it refrains from starting another one
queue_run_max = 30
##

## If the system load average is higher than this value, incoming messages from all sources are queued, and no automatic deliveries are started. If this happens during local or remote SMTP input, all subsequent messages on the same connection are queued
queue_only_load = 30
##

## If this option is set greater than zero, it specifies the maximum number of original recipients for any message. Additional recipients that are generated by aliasing or forwarding do not count
recipients_max = 100

## The four check_... options allow for checking of disk resources before a message is accepted. check_spool_space and check_spool_inodes check the spool partition if either value is greater than zero
check_spool_inodes = 100
check_spool_space = 20M
##
smtp_accept_reserve = 400
smtp_reserve_hosts = chaos.xxx.com:10.0.0.27:127.0.0.1:10.0.0.52


# IDENT
rfc1413_hosts = *
rfc1413_query_timeout = 0s

# The setting below causes Exim to do a reverse DNS lookup on all incoming
# IP calls, in order to get the true host name. If you feel this is too
# expensive, you can specify the networks for which a lookup is done, or
# remove the setting entirely.

#host_lookup = *

# Allow funy hello characters..
helo_allow_chars = _

# QUEUE Options
auto_thaw = 5m
ignore_bounce_errors_after = 1h
timeout_frozen_after = 10m

# ExiList Hack
EXILIST_HOME=/var/www/html/exilist
EXILIST_BIN=EXILIST_HOME/exilist.mgr.pl
EXILIST_UID=apache
EXILIST_GID=web

######################################################################
#                       ACL CONFIGURATION                            #
#         Specifies access control lists for incoming SMTP mail      #
######################################################################


begin acl

#acl_check_blist:
#deny hosts = partial()lsearch;/etc/exim/sa-blacklist.current.domains
# message = $sender_host_address Blocked by http://www.stearns.org/sa-blacklist/


check_etrn:
        accept hosts = *
        deny    hosts = *
        message = Access Denied!! !!!! the flip flop


acl_check_rcpt:
        accept  hosts = : 127.0.0.1
    deny senders = :
         domains = domain1.com : domain2.com
         message = No valid Sender specified


        deny    local_parts   = ^.*[@%!/|] : ^\\.
        accept  local_parts   = postmaster
        domains               = +local_domains
        deny    message       = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
#       dnslists      = sbl-xbl.spamhaus.org:relays.ordb.org:dul.dnsbl.sorbs.net:multi.surbl.org
        dnslists      = sbl-xbl.spamhaus.org:relays.ordb.org:multi.surbl.org



  accept  domains       = +local_domains
          endpass
          message       = unknown user
          verify        = recipient
          delay         = 20s


  accept  domains       = +relay_to_domains
          endpass
          message       = unrouteable address
          verify        = recipient
          delay         = 20s


  accept  hosts         = +relay_from_hosts
# Added recently by GM
#  deny
 #         message     = unknown user
  #        !verify     = recipient/callout=20s,defer_ok,use_sender
   #       delay       = ${eval:$rcpt_fail_count*10 + 20}s


  accept  authenticated = *
          delay         = 20s


#  deny    message       = relay not permitted - admin@???


acl_check_content:
    deny    message = This message contains an unwanted file extension ($found_extension)
             demime = scr:com:vbs:bat:lnk:pif


        accept


######################################################################
#                      ROUTERS CONFIGURATION                         #
#               Specifies how addresses are handled                  #
######################################################################
#     THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT!       #
# An address is passed to each router in turn until it is accepted.  #
######################################################################


begin routers

dnslookup:
        driver = dnslookup
        domains = ! +local_domains
        transport = remote_email
        ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
        no_more


amavis:
       driver = manualroute
       transport = amavis
       route_list = "* localhost byname"
       self = send
       condition = "${if or {{eq {$interface_port}{10025}} \
                         {eq {$received_protocol}{spam-scanned}} \
                         {eq {$sender_address}{}} \
                        }{0}{1}}"


autorespond:
        driver = accept
        condition = ${if eq{} {${lookup mysql{SELECT autoresponder FROM email WHERE autoresponder='YES' AND address="$local_part" AND domain="$domain" AND in_use='1'}}}{no}{yes}}
        no_verify
        no_expn
        unseen
        transport = auto_responder


email:
        driver = accept
        condition = ${if eq{} {${lookup mysql {SELECT address FROM email WHERE address="$local_part" AND domain="$domain" AND in_use='1' and email_type="1" }}}{no}{yes}}
        transport = local_email


wildcards:
        driver = redirect
        file_transport = address_file
        pipe_transport = address_pipe
        data = ${lookup mysql{SELECT pointer FROM email WHERE address="@" AND domain="$domain" AND email_type='3'}}


system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
file_transport = address_file
pipe_transport = address_pipe

aliases:
        driver = redirect
        file_transport = address_file
        pipe_transport = address_pipe
        data = ${lookup mysql{SELECT pointer FROM email WHERE address="$local_part" AND domain="$domain" AND email_type="2"}}


exilist_post_router:
    driver = accept
    verify_sender = false
    condition = ${lookup mysql {select id from lists where name='$local_part' and domain='$domain'}}
    transport = exilist_post_transport


exilist_bounce_router:
    driver = accept
    verify_sender = false
    condition = ${if match {$local_part}{^[0-9]+_return_[0-9]+\\.[A-Za-z0-9-]+\$}{1}{0}}
                transport = exilist_bounce_transport


localuser:
driver = accept
check_local_user
transport = local_delivery
cannot_route_message = Unknown user


######################################################################
#                      TRANSPORTS CONFIGURATION                      #
######################################################################
#                       ORDER DOES NOT MATTER                        #
#     Only one appropriate transport is called for each delivery.    #
######################################################################


begin transports

amavis:
        driver = smtp
    hosts = 10.0.0.52
        port = 10024
        allow_localhost
        user = exim
    hosts_override


remote_email:
        driver = smtp
        user = exim


local_email:
        driver = appendfile
        file = /var/mail/$domain/$local_part
        create_directory
        delivery_date_add
        envelope_to_add
        return_path_add
        user = web
        group = web
        mode = 0660
        directory_mode = 0770
        quota = ${lookup mysql{select mquota from email where address="$local_part" and domain="$domain"}{$value} {5M}}
        quota_warn_threshold = 90%
        quota_warn_message = "\
        To: $local_part@$domain\n\
        Subject: Your mailbox\n\n\
        Greetings\n\n\
        Your mailbox is using 90% of its quota.\n\
        For further information contact your ISP Support.\n\n\
        \n\n\"


auto_responder:
        driver   = autoreply
        reply_to = "${local_part}@${domain}"
        from = "${local_part}@${domain}"
        to       = "${sender_address}"
        once = "/autoreply/${domain}-${local_part}"
        once_repeat = 500s
#       headers  = "MIME-Version: 1.0\n\
#Content-type: text/html; charset=iso-8859-1\n"


        subject  = ${lookup mysql{SELECT arsubject FROM email WHERE address="$local_part" AND domain="$domain"}{$value}{Automatic reply from ${local_part}@${domain}}}
        text     = ${lookup mysql{SELECT artext FROM email WHERE address="$local_part" AND domain="$domain"}{$value}}
        user = web
        group = web


exilist_post_transport:
    driver = pipe
    command = EXILIST_BIN "${lookup mysql {select id from lists where name='$local_part' and domain='$domain'}}" post none $message_id $sender_address $reply_address
    user = EXILIST_UID
    group = EXILIST_GID
    current_directory = EXILIST_HOME
    home_directory = EXILIST_HOME
    return_fail_output


exilist_bounce_transport:
    driver = pipe
    command = EXILIST_BIN ${extract{1}{_}{$local_part}} ${extract{2}{_}{$local_part}} ${extract{3}{_}{$local_part}} $message_id $sender_address $reply_address
    user = EXILIST_UID
    group = EXILIST_GID
    current_directory = EXILIST_HOME
    home_directory = EXILIST_HOME
    return_fail_output


local_delivery:
driver = appendfile
file = /var/mail/$domain/$local_part
delivery_date_add
envelope_to_add
return_path_add

#localuser:
# driver = accept
# check_local_user
# transport = local_delivery
# cannot_route_message = Unknown user

######################################################################
#                      RETRY CONFIGURATION                           #
######################################################################


begin retry

# Domain               Error            Retries
# ------               -----            -------
*                                               quota
*                                               *                       F,2h,15m; G,16h,1h,1.5; F,3d,6h




######################################################################
#                      REWRITE CONFIGURATION                         #
######################################################################


# There are no rewriting specifications in this default configuration file.

begin rewrite



######################################################################
#                   AUTHENTICATION CONFIGURATION                     #
######################################################################


# There are no authenticator specifications in this default configuration file.

begin authenticators

######################################################################
#                   CONFIGURATION FOR local_scan()                   #
######################################################################


# If you have built Exim to include a local_scan() function that contains
# tables for private options, you can define those options here. Remember to
# uncomment the "begin" line. It is commented by default because it provokes
# an error with Exim binaries that are not built with LOCAL_SCAN_HAS_OPTIONS
# set in the Local/Makefile.

# begin local_scan


# End of Exim configuration file
[root@mx01 root]#