Performances

LemonLDAP::NG is designed to be very performant. En particulier, il utilise les capacités multi-threads d'Apache-2, donc pour optimiser les performances, utilisez de préférence mpm-worker.

Global performance

On linux, by default, there is no DNS cache and LemonLDAP::NG portal request DNS at every connexions on LDAP or DB. Under heavy loads, that can generated hundred of DNS queries and many errors on LDAP connexions (timed out) from IO::Socket.

To bypass this, you can: * Use IP in configuration to avoid DNS resolution * Install a DNS cache like nscd, netmask or bind

Performance des agents (handlers)

Les agents vérifient les droits et calculent les en-têtes pour chaque requête HTTP. Donc pour augmenter les performances, évitez les règles trop complexes en utilisant les macros, groupes ou macros locales.

Macros et groupes

Les macros et les groupes sont calculées pendant le processus d'authentification par le portail :

Exemples de macros:

# macro booléenne
isAdmin -> $uid eq 'foo' or $uid eq 'bar'
# autre macro 
displayName -> $givenName." ".$surName
 
# Utiliser une macro booléenne dans une règle
^/admin -> $isAdmin
# Utiliser une macro chaîne dans un en-tête HTTP
Display-Name -> $displayName

Exemples de groupes:

# groupe
admin -> $uid eq 'foo' or $uid eq 'bar'
 
# Utiliser un groupe dans une règle
^/admin -> $groups =~ /\badmin\b/

Noter que les groupes sont calculés après les macros, donc une règle de groupe peut utiliser une valeur issue d'une macro.

Egalement, les macros et groupes sont calculés dans l'ordre alpha-numerique, c'est à dire dans l'ordre d'affichage dans le manager. Par exemple, la macro “macro1” sear calculée avant la macro “macro2” : donc l'expression de macro2 peut utiliser la valeur $macro1. De même pour les groupes : une règle de groupe peut en utiliser une autre calculée précédemment.

Macros locales

Les macros et les groupes sont stockées dans la base de données des sessions. Les macros locales sont une fonctionnalité spéciale des agents qui permettent d'avoir des macros utilisables localement seulement. Ces macros sont calculées seulement à leur premier usage et stockées dans le cache local des sessions (uniquement pour ce serveur) et seulement si l'utilisateur accède à l'application relative. Ce dispositif évite de stocker trop de données.

# règle
admin -> $admin ||= ($uid eq 'foo' or $uid eq 'bar')
# en-tête
Display-Name -> $displayName ||= $givenName." ".$surName

Notez que cette fonctionnalité n'est intéressante que pour les systèmes Lemonldap::NG protégeant un grand nombre d'applications

Performances du portail

Performances générales

Le portail est le composant le plus gros de Lemonldap::NG. Il est recommendé d'utiliser ModPerl::Registry au lieu d'utiliser le dispositif "cgi-script" tel qu'indiqué dans les fichiers de configuration d'Apache proposés en exemple (portal-apache2.conf):

<Files *.pl>
    SetHandler perl-script
    PerlResponseHandler ModPerl::Registry
</Files>

On peut utiliser un serveur FastCGI en utilisant le fichier index.fcgi disponible dans les exemples du portail.

Accès à la configuration

En mettant useLocalConf à 1 dans lemonldap-ng.ini (section [Portal]), le portail utilisera la configuration cachée. Pour la rafraîchir, il faut installer un agent (handler) sur le même serveur pour utiliser le mécanisme de rafraîchissement ou redémarrer le serveur à chaque changement.

Performances au démarrage

Pour accélérer le démarrage du portail lorsque le serveur est relancé, ajoutez les lignes suivantes dans les fichiers de configuration d'Apache (tel que proposé dans portal-apache2.conf):

<Perl>
    require Lemonldap::NG::Portal::SharedConf;
    Lemonldap::NG::Portal::SharedConf->compile(
        qw(delete header cache read_from_client cookie redirect unescapeHTML));
    # Décommentez cette ligne si vous utilisez le menu Lemonldap::NG
    require Lemonldap::NG::Portal::Menu;
    # Décommentez cette ligne si vous utilisez les capacités SOAP du portail
    require SOAP::Lite;
</Perl>

Performances d'Apache::Session

Les agents (handlers) Lemonldap::NG utilisent un cache local pour stocker les sessions (pour 10 minutes). Ainsi, les modules Apache::Session ne posent pas de problèmes aux agents. En revanche, ce peut-être un frein pour le portail :

  1. Lorsque sont activées les paramètres de restriction d'ouverture de session, celles-ci sont toutes examinées à chaque nouvelle authentification sauf lorsqu'un module de la famille Apache::Session::Browseable est utilisé.
  2. Comme MySQL ne dispose pas toujours de dispositif de transaction, Apache::Session::MySQL a été conçu en utilisant les verrous MySQL. Ceci dégrade fortement les performances de MySQL, si vous voulez stocker les sessions dans une base de données MySQL, utilisez l'une des solutions suivantes

Remplacer MySQL par Apache::Session::Flex

Dans le champ “Module Apache::Session”, indiquez ”Apache::Session::Flex” et utilisez les paramètres suivants :

Store      -> MySQL
Lock       -> Null
Generate   -> MD5
Serialize  -> Storable
DataSource -> dbi:mysql:sessions;host=...
UserName   -> ...
Password   -> ...

Depuis la version 1.90 d'Apache::Session, on peut utiliser Apache::Session::MySQL::NoLock à la place

Utiliser Apache::Session::Browseable

Apache::Session::Browseable est une surcouche d'autres modules Apache::Session qui ajoute des capacités d'indexation. Pour l'utiliser (avec MySQL par exemple), choisissez “Apache::Session::Browseable::MySQL” comme “Module Apache::Session” et utilisez les paramètres suivants :

DataSource -> dbi:mysql:sessions;host=...
UserName   -> user
Password   -> password
Index      -> ipAddr uid

Notez que Apache::Session::Browseable::MySQL n'utilise pas les verrous MySQL.

Un module Apache::Session::Browseable::Redis a été créé, c'est le plus rapide (excepté pour l'explorateur de sessions, battu par Apache::Session::Browseable::DBI/LDAP >= 1.0)

Certains modules Apache::Session ne sont pas utilisables par Lemonldap::NG tel Apache::Session::Memcached, car ce module n'offre pas de dispositif de parcours des sessions

Performances LDAP

Le serveur LDAP peut être un frein lorsque vous utilisez la récupération des groupes LDAP. Vous pouvez contourner cette dificulté en utilisant les champs “memberOf” dans votre schéma LDAP :

dn: uid=foo,dmdName=people,dc=example,dc=com
...
memberOf: cn=admin,dmdName=groups,dc=example,dc=com
memberOf: cn=su,dmdName=groups,dc=example,dc=com

Ainsi au lieu d'utiliser la récupération des groupes LDAP, vous avez juste à stocker le champ “memberOf” dans vos variables exportées. Avec OpenLDAP, vous pouvez utiliser memberof overlay qui le fera automatiquement.

N'oubliez pas de créer un index sur le champ utilisé pour trouver les utilisateurs (uid par défaut)

Pour éviter de stocker les dn dans votre base de sessions, vous pouvez utiliser une macro pour réécrire memberOf :

  • Variables exportées
ldapgroups -> memberOf
Pour l'instant, ldapgroups contient “cn=admin,dmdName=groups,dc=example,dc=com cn=su,dmdName=groups,dc=example,dc=com”
  • Une petite macro :
ldapgroups -> join(" ",($ldapgroups =~ /cn=(.*?),/g))
Maintenant, ldapgroups contient “admin su”