Les trucs et astuces de ce document vous aideront à améliorer les performances des systèmes Postfix qui fonctionnent déjà. Si votre système Postfix n'est pas capable de recevoir et livrer du courrier, vous devez d'abord résoudre ces problèmes en utilisant au besoin la page DEBUG_README.
Pour optimiser les performances d'un filtre externe de contenu, consultez d'abord les pages FILTER_README et SMTPD_PROXY_README. Assurez-vous ensuite que le code du filtre de contenu ne comporte pas de latence. Autant que possible, évitez le recours aux sources de données externes ajoutant un délai non négligeable. Votre filtre de contenu doit fonctionner avec une faible concurrence pour éviter les surcharges de CPU/mémoire. Les sites à fort trafic devront éviter les consultations RBL, requêtes aux bases de données complexes et ainsi de suite.
Éléments de performance de la réception du courrier :
Éléments de performance de la livraison du courrier :
Autres éléments de performance :
Les outils suivants peuvent être utilisés pour mesurer les performances du système de messagerie sous une charge artificielle. Ils ne sont normalement pas installés avec Postfix.
Avant de commencer, vous devez avoir compris les notions de file d'attente maildrop, file d'attente entrante, et file d'attente active présentées à la page QSHAPE_README.
Lancez un serveur DNS local pour réduire le temps de latence des consultations DNS. Si vous utilisez de multiples systèmes Postfix, faites pointer chaque serveur DNS local sur le même serveur partagé pour réduire le nombre de consultations au travers du réseau.
Eliminez les consultations LDAP non nécessaires, en indiquant un filtre de domaine. Ceci élimine les consultation pour des adresses extérieures, et élimine les consultations d'adresses partielles. Lisez ldap_table(5) pour plus de détails.
Lorsque Postfix répond lentement aux clients SMTP :
Recherchez les symptomes de problèmes tel que décrit à la page DEBUG_README et éliminez d'abord ces problèmes.
Désactivez les examens header_checks et body_checks et regardez si le problème persiste.
Désactivez la mise en cage chroot tel que décrit à la page DEBUG_README et regardez si le problème persiste.
Si Postfix enregistre le client SMTP comme "unknown" dans les journaux, vous avez un problème de service DNS : le serveur n'est pas le bon ou le fichier resolv.conf contient de mauvaises informations, ou encore un pare-feu bloque les requêtes ou les réponses DNS.
Si le nombre de processus smtpd(8) atteint la limite autorisée indiquée dans le fichier master.cf, les nouveaux clients SMTP doivent attendre qu'un processus se libère. Augmentez la limite si la mémoire le permet. Lisez les instructions données au paragraphe "Optimiser le nombre de processus Postfix".
Avec les versions 2.0 et antérieures de Postfix, le serveur smtpd(8) attend avant de rapporter une erreur à un client SMTP. Cette idée est appelée "tar pitting". Toutefois, ces délais ralentissent également Postfix. Lorsque le serveur smtpd(8) repond lentement, les sessions prennent plus de temps et ainsi plus de processus smtpd(8) sont nécessaires pour absorber la charge. Lorsque la limite des processus serveur smtpd(8) de Postfix est atteinte, les nouveaux clients doivent attendre qu'un processus se libère ralentissant ainsi tous les clients.
Vous pouvez accélerer accélerer le traitement des erreurs du serveur smtpd(8) en désactivant ce délai :
/etc/postfix/main.cf: # Pas nécessaire avec Postfix >= 2.1 smtpd_error_sleep_time = 0
En renseignant ainsi le paramètre, les versions 2.0 et antérieures de Postfix peuvent servir plus de clients avec le même nombre de processus serveur SMTP. Le paragraphe suivant décrit comment Postfix traite les clients qui commettent beaucoup d'erreurs.
Le serveur smtpd(8) de Postfix maintient un compteur d'erreurs par session. Celui-ci est remis à zéro lorsqu'un message est correctement transféré et est incrémenté lorsqu'une requête client n'est pas reconnue ou non implémentée, lorsqu'une requête viole une restriction d'accès, ou lorsque d'autres erreurs apparaissent.
Au fur et à mesure que le compteur d'erreurs par session croît, le serveur smtpd(8) change de comportement et commence à insérer des délais avant les réponses. L'idée est de ralentir ces clients pour limiter l'emploi des ressources. Ce comportement dépend des versions de Postfix.
IMPORTANT : Ces délais ralentissent également Postfix. Lorsqu'un trop fort délai est configuré, le nombre de sessions SMTP simultanées croît jusqu'à atteindre la limite des processus smtpd(8) et les nouveaux clients SMTP doivent attendre qu'un serveur smtpd(8) se libère.
Postfix version 2.1 et supérieures :
Lorsque le compteur d'erreurs atteint $smtpd_soft_error_limit (défaut : 10), le serveur smtpd(8) ralentir toutes les réponses consécutives ou non à une erreur de $smtpd_error_sleep_time secondes (défaut : 1 seconde).
Lorsque le compteur d'erreur atteint $smtpd_hard_error_limit (défaut : 20) le serveur smtpd(8) de Postfix coupe la connexion.
Postfix version 2.0 et antérieures :
Lorsque le compteur d'erreur est inférieur à $smtpd_soft_error_limit (défaut : 10), le serveur smtpd(8) de Postfix patiente $smtpd_error_sleep_time secondes avant chaque réponse consécutive à une erreur (1 seconde avec Postfix 2.0, 5 secondes avec Postfix 1.1 et antérieurs).
Lorsque le compteur d'erreurs atteint $smtpd_soft_error_limit, le serveur smtpd(8) de Postfix retarde toutes les réponses de "nombre d'erreurs" secondes ou $smtpd_error_sleep_time, s'il est plus élevé.
Lorsque le compteur d'erreurs atteint $smtpd_hard_error_limit (défaut: 20) le serveur smtpd(8) de Postfix coupe la connexion.
Note : cette fonctionnalité n'est pas inclus dans Postfix version 2.1.
Le serveur smtpd(8) de Postfix peut limiter le nombre de connexions simultanées venant du même client SMTP, ainsi que le nombre de connexions que le client est autorisé à faire par unité de temps. Ces statistiques sont maintenues par le serveur anvil(8) (explication : si anvil(8) s'arrête, les limites de connexions ne sont plus comptées).
IMPORTANT : Ces limites sont conçues pour proteger le serveur smtpd(8) contre les abus flagrants. N'utilisez pas ces limites pour réguler le trafic légitime du courrier : le courrier sera grossièrement ralenti.
Un client SMTP peut effectuer $smtpd_client_connection_count_limit connexions simultanées (défaut : 50). Ceci est la moitié de la limite par défaut des processus.
Un client SMTP peut livrer $smtpd_client_message_rate_limit messages par unité de temps (défaut : pas de limites).
Un client SMTP peut adresser $smtpd_client_recipient_rate_limit destinataires par unité de temps (défaut : pas de limites).
Un client SMTP peut effectuer $smtpd_client_connection_rate_limit connexions par unité de temps (défaut : pas de limites).
Ces limites ne sont pas appliquées aux clients SMTP des réseaux indiqués par $smtpd_client_connection_limit_exceptions (défaut : les clients des réseaux $mynetworks peuvent faire un nombre illimité de connexions).
Le paramètre anvil_rate_time_unit indique l'unité de temps pendant laquelle les taux de connexions client sont évalués (défaut : 60s).
Avant de commencer, vous devez avoir compris les notions de file d'attente maildrop, file d'attente entrante, file d'attente active et file d'attente retardée présentées à la page QSHAPE_README.
En cas de livraison lente, lencez l'outil qshape comme décrit à la page QSHAPE_README.
Soumettez plusieurs destinataires par message au lieu de soumettre les messages avec seulement quelques destinataires.
Soumettez le courrier via SMTP au lieu d'utiliser /usr/sbin/sendmail. Vous devez ajuster le paramètre smtpd_recipient_limit.
Ne surchargez pas le disque avec trop de soumission de messages. Optimisez le taux de soumission en ajustant le nombre de soumissions parallèles et/ou la valeur du paramètre in_flow_delay.
Lancez un serveur DNS local pour réduire la latence des consultations DNS. Si vous utilisez plusieurs systèmes Postfix, faites pointer chaque serveur DNS local vers un serveur relais partagé pour réduire le nombre de consultations à travers le réseau.
Reduisez les valeurs smtp_connect_timeout et smtp_helo_timeout pour que Postfix n'ai pas trop de connexions semi-ouvertes avec des serveurs smtpd(8) ne répondant pas.
Utilisez un transporteur de messages dédié pour les destinations à problème, avec des timeouts réduits et une concurrence ajustée. Reportez-vous au paragraphe "Optimiser le nombre de livraisons simultanées" ci-dessous.
Utilisez une machine fallback_relay pour le courrier qui ne peut être livré à la première tentative. Cette machine "garde-fou" peut utiliser des délais entre tentatives plus courts pour atteindre les destinations à problème. Reportez-vous au paragraphe "Optimiser la fréquence de tentatives de livraison du courrier retardé" ci-dessous.
Accélérez les mises à jour du disque avec un grand cache d'écriture persistant (64MB). Ceci autorise les mises à jour à être triées pour optimiser la vitesse d'accès sans compromettre l'intégrité du système de fichier lorsque le système plante.
Utilisez un disque à état solide (un disque RAM persistant). C'est une solution chère qui peut être utilisée en combinaison avec des temps limites SMTP courts et une machine "garde-fou" fallback_relay qui traite le courrier des destinations à problème.
Bien que Postfix puisse être configuré pour faire fonctionner 1000 processus client SMTP en même temps, il est rarement souhaitable qu'il fasse 1000 connexions simultanées vers la même machine distante. Pour cette raison, Postfix dispose de mécanismes de sûreté pour éviter ce problème (nommé "thundering herd").
Le gestionnaire des files d'attente implémente l'équivalent de la stratégie de démarrage lent du protocole TCP : lors de la livraison ves un site, il envoie un petit nombre de messages dans un premier temps puis augmente la concurrence tant que tout va bien et augmente la concurrence en cas de congestion.
Le paramètre initial_destination_concurrency (défaut : 5) contrôle le nombre de messages initialement envoyés à la même destination avant d'adapter la concurrence de livraison. Bien sûr, cette valeur est effective seulement tant qu'elle n'excède pas la limite des processus et de concurrence du transporteur.
Le paramètre default_destination_concurrency_limit (défaut : 20) contrôle le nombre de messages qui peuvent être envoyés à la même destination simultanément. Vous pouvez surcharger cette valeur pour un transporteur de messages particulier en ajoutant son nom d'entrée master.cf devant "_destination_concurrency_limit".
Exemples de limites de concurrence spécifique à un transporteur :
Le paramètre local_destination_concurrency_limit (défaut : 2) contrôle le nombre de messages délivrés simultanément au même destinataire local. La valeur limite recommendée est basse car la livraison à la même boîte-aux-lettres doit être faite séquentiellement, rendant inutile le parallèlisme massif. Une autre bonne raison de limiter la concurrence de livraison au même destianatire : si le destinataire a une commande shell coûteuse dans son fichier .forward, ou si le destinataire est un gestionnaire de liste de diffusion, vous ne souhaiterez sans doute pas lancer trop d'instances de ce processus en même temps.
La valeur par défaut smtp_destination_concurrency_limit=20 semble suffisante pour charger sensiblement un système sans l'envoyer dans ses limites. Faites attention si vous élevez cette valeur.
Les valeurs par défaut de limite concurrence ci-dessus correspondent parfaitement à un large panel de situations. Un changement non réfléchit de ces paramètres face à une congestion peut aggraver le problème. En particulier, les fortes concurrences de destinatation ne doivent jamais être générales. Elles ne doivent être utiliseés que pour les transporteurs qui livrent un petit nombre de sites à fort volume.
Une situation commune où une forte concurrence est souhaitable concerne les passerelles relayant un fort volume de messages entre Internet et un intranet. Approximativement la moitié des messages (en supposant que les trafics entrant et sortant sont équivalents en volume) seront destinés au commutateur interne. Comme ces commutateurs de messages recevront du courrier externe eniquement de la passerelle, il est raisonnable de configurer la passerelle pour faire des requêtes plus lourdes sur les serveurs SMTP internes.
L'optimisation des limites de concurrence entrantes doit être testé. Un commutateur à forte capacité devrait être capable de traiter 50 à 100 connexions simultanées (au lieu de 20 par défaut), en particulier si la passerelle transfert le courrier de multiples machines MX. Lorsque toutes les machines MX sont actives et acceptent les connexions en temps réel, le taux de transfert sera élevé. Si une de ces machines MX est hors service et ne répond pas du tout, la latence de connexion correspondante décroît de 1/N * $smtp_connection_timeout, où N est le nombre de machines MX. ces limites descendent au plus à (concurrence de la destination * N / $smtp_connection_timeout.
Par exemple, avec une concurrence de destination fixée à 100 et 2 machines MX, chaque machine recevra 50 connexions simultanées. Si un MX s'arrête et que le temps limite de connexion SMTP par défaut est de 30s, la limite de transfert est de 100 * 2 / 30 ~= 6 messages par seconde. Ceci montre que les destinations à fort volume avec une bonne connectivité et de multiples machines MX ont besoin d'un temps limite de connexion plus bas, des valeurs de l'ordre de 5s voire 1s peuvent être utilisées pour prévenir les congestions lorsqu'un ou plus, mais pas toutes les machines MX sont hors service.
Si nécessaire, mettez une plus forte valeur transporteur_destination_concurrency_limit (dans main.cf car il s'agit d'un paramètre du gestionnaire des files d'attente) et une plus basse valeur smtp_connection_timeout (avec l'option "-o" dans master.cf pour surcharger le paramètre main.cf car ce paramètre n'est pas relatif à un transporteur) pour le transporteur relais et tous les transporteurs dédiés aux destinatations à fort volume.
Le paramètre default_destination_recipient_limit (défaut : 50) contrôle le nombre de destinataires qu'un agent de livraison de Postfix inclura dans chaque copie dun message. Vous pouvez surcharger ce paramètre pour des agents de livraison particuliers. Par exemple, "uucp_destination_recipient_limit = 100" limitera le nombre de destinataires UUCP à 100.
Si un message excède la limite de destinatires pour une destination, le gestionnaire des files d'attente de Postfix coupera la liste des destinataires en de plus petites listes. Postfix tentera d'envoyer de multiples copies du message en parallèle.
IMPORTANT : Faites attention en augmentant la limite des destinataires par livraison de message ; certains serveurs smtpd(8) coupent la connexion lorsqu'ils dépassent la mémoire allouée ou lorsque la limite des destinataires est atteinte, et le message n'est jamais livré.
Le paramètre smtpd_recipient_limit (défaut : 1000) contrôle le nombre de destinataires que serveur smtpd(8) de Postfix acceptera par livraison. La limite par défaut est supérieure à ce qu'un client SMTP raisonnable enverra. Cette limite existe pour protéger le système de messagerie local contre un client tournant en boucle.
Lorsqu'un agent de livraison de Postfix (smtp(8), local(8), etc.) n'est pas capable de livrer un message il peut blamer le message lui-même, ou blamer la partie tierce.
Lorsque l'agent de livraison blame un message, le gestionnaire des files d'attente donne au fichier en file d'attente une date de modification dans le futur, ainsi il ne sera pas traité avant. Par défaut, le temps d'attente est le temps depuis que le message est arrivé. Ce résultat est appelé "exponential backoff behavior".
Lorsqu l'agent de livraison blame la partie receptionnaire (par exemple un utilisateur destinataire local, ou une machine distante), le gestionnaire des files d'attente n'avance pas seulement la date du fichier dans la file d'attente, mais met également cette partie tierce dans une liste "morte" pour qu'elle soit ignorée pendant un certain temps.
Ce processus est gouverné par quelques paramètres.
- queue_run_delay (défaut : 1000 secondes)
- Fréquence d'examen de la file d'attente retardée par le gestionnaire des files d'attente.
- minimal_backoff_time (défaut : 1000 secondes)
- Délai minimum avant nouvel examen et délai minimum de mise en liste "morte".
- maximal_backoff_time (défaut : 4000 secondes)
- Délai maximum avant nouvel examen suite à un échec de livraison.
- maximal_queue_lifetime (défaut : 5 jours)
- Délai à partir duquel un message est retourné comme non livrable. Indiquez 0 pour retourner les messages immédiatement après le premier échec de livraison.
- bounce_queue_lifetime (défaut : 5 jours, disponible à partir de la version 2.1 de Postfix)
- Temps maximum de présence d'un message MAILER-DAEMON en file d'attente avant qu'il soit considéré non livrable. Indiquez 0 pour supprimer ces messages dès le premier échec.
- qmgr_message_recipient_limit (défaut : 20000)
- Taille de beaucoups de structures de données en mémoire du gestionnaire des files d'attente. Entre autres, ce paramètre limite la taille de la liste volatile en mémoire des destinations "mortes". Les destinations supplémentaires ne sont pas ajoutées.
IMPORTANT : si vous augmentez la fréquence de tentative de livraison des messages retardés ou si vous videz la file d'attente des messages retardés, vous pourrez trouver que les performances de Postfix se dégradent. Les symptomes sont les suivants :
La file d'attente active est saturée avec les messages à problème. Les nouveaux messages entrent dans la file d'attente active seulement lorsqu'un vieux message est retardé. C'est un processus qui atteint généralement les limites de temps d'une ou plusieurs connexions SMTP.
Tous les agents de livraison disponibles sont rapidement occupés à tenter de se connecter à des sites non joignables. Les nouveaux messages doivent attendre qu'un agent de livraison se libère. C'est un processus qui atteint généralement les limites de temps d'une ou plusieurs connexions SMTP.
Losque le courrier est frequemment retardé, règler le problème est toujours meilleur que d'augmenter la fréquence des tentatives de livraisons. Toutefois, si vous ne pouvez contrôler que cette fréquence, utilisez une machine fallback_relay "garde-fou" dédiée pour les destinations à problème ainsi elles ne ruinent pas les performances de la livraison normale.
Le paramètre de configuration default_process_limit donne un contrôle direct sur le nombre de processus démons que Postfix lancera. Depuis Postfix 2.0 la limite est fixée à 100 processus client smtp, 100 processus serveurs smtp, et ainsi de suite. Celà peut dépasser les capacités des systèmes pauvres en mémoire comme des réseaux à faible bande passante.
Vous pouvez changer la limite globale des processus en renseignant default_process_limit dans le fichier main.cf. Par exemple, pour lancer 10 processus client smtp, 10 processus serveur smtp et ainsi de suite :
/etc/postfix/main.cf: default_process_limit = 10
Vous devez lancer "postfix reload" pour activer ces changements. Les limites sont contrôlées par le démon master(8) de Postfix qui ne relit pas automatiquement main.cf lorsqu'il change.
Vous pouvez surcharger la limite des processus pour des démons particulier de Postfix en éditant le fichier main.cf de Postfix. Par exemple, si vous ne voulez pas recevoir 100 messages SMTP en même temps, mais ne voulez pas changer les limites de processus pour la livraison locale, vous pouvez indiquer :
/etc/postfix/master.cf: # ==================================================================== # service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) # ==================================================================== . . . smtp inet n - - - 10 smtpd . . .
Lorsque Postfix ouvre trop de fichiers ou de sockets, les processus plantent et le système enregistre des erreurs "file table full".
Reduisez le nombre de processus comme décrit au paragraphe "Optimiser le nombre de processus Postfix" ci-dessus. Moins de processus ouvrent moins de fichiers et de sockets.
Configurez le noyau pour ouvrir plus de fichiers et de sockets. Ces détails sont très dépendants du système et changent avec les versions du système d'exploitation. Assurez-vous de vérifier ces informations avec votre guide d'optimisation du système :
Certains paramètres de noyaux FreeBSD peuvent être indiqués dans le fichier /boot/loader.conf, et d'autres peuvent être changés avec les commandes sysctl suivant le numéro de version.
kern.ipc.maxsockets="5000" kern.ipc.nmbclusters="65536" kern.maxproc="2048" kern.maxfiles="16384" kern.maxfilesperproc="16384"
Les paramètres du noyau Linux peuvent être indiqué dans le fichier /etc/sysctl.conf et peuvent être également changés avec les commandes sysctl :
fs.file-max=16384 kernel.threads-max=2048
Les paramètres du noyau Solaris peuvent être indiqués dans le fichier /etc/system, tel que décrit dans l'entrée "How can I increase the number of file descriptors per process?" de la page Solaris FAQ.
* set hard limit on file descriptors set rlim_fd_max = 4096 * set soft limit on file descriptors set rlim_fd_cur = 1024
traduction par Xavier Guimard - Retour au menu