Le dicton « Faites d’abord en sorte que ça marche, puis faites en sorte que ça aille vite » peut faire plus de mal que de bien.

On a vous a peut-être déjà seriné le conseil suivant en matière de programmation « Faites d’abord en sorte que ça marche, puis faites en sorte que ça aille vite ».. Ce n’est pas entièrement faux. Toutefois, sans le contexte approprié, il est généralement mal interprété et mal appliqué.

Ce conseil vise à empêcher le développeur ou la développeuse d’optimiser prématurément du code qui serait rarement, voir jamais exécuté, à tel point que l’effort d’optimisation ne serait pas justifié. En outre, l’optimisation peut conduire à un code plus complexe et introduire ainsi des bugs. Ainsi, si vous effectuez du développement, ne passez pas trop de temps sur la micro-optimisation de chaque ligne de code. Veillez simplement à choisir les structures de données, les bibliothèques et les algorithmes appropriés. Attendez que l’analyse de la zone réactive d’un profileur indique où une optimisation plus approfondie pourrait augmenter les performances globales.

Décisions architecturales et artefacts

Cependant, le conseil « Faites d’abord en sorte que ça marche, puis faites en sorte que ça aille vite » est complètement faux quand il s’agit de décisions « architecturales ». Que sont les décisions architecturales ? En termes simples, ce sont des décisions qui sont coûteuses, difficiles et/ou impossibles à modifier par la suite. Gardez à l’esprit que « coûteux » est parfois identique à « impossible ». Par exemple, lorsque votre projet manque de budget, les modifications coûteuses sont impossibles à mettre en œuvre. Les changements d’infrastructures sont le tout premier type de changements de cette catégorie qui viennent à l’esprit de la plupart des gens. Mais il existe un autre type d’artefact « architectural » qui peut se révéler compliqués à modifier :

  1. il s’agit des éléments de code « centraux » d’une application, sur lesquels beaucoup d’autres éléments s’appuient. Pour les modifier, toutes les dépendances doivent être également modifiées et testées à nouveau simultanément.

  2. Les artefacts, qui sont impliqués dans certains scénarios asynchrones dépendant du timing où l’entrée – et donc le comportement du système – peut varier de manière très aléatoire. Les changements peuvent avoir des effets imprévisibles et être difficiles à tester.

  3. Il s’agit des modèles de logiciels qui sont réutilisés à l’infini dans toutes les parties du système. Si le modèle logiciel se révèle sous-optimal, tous les artefacts qui l’utilisent doivent être recodés.

Mémoriser ? Nous avons expliqué plus haut que le Dispatcher est un élément essentiel d’une application AEM. L’accès à une application web est très aléatoire, car les utilisateurs et utilisatrices se connectent et se déconnectent à des moments imprévisibles. En fin de compte, tout le contenu est (ou doit être) mis en cache dans le Dispatcher. C’est la raison pour laquelle les personnes attentives auront peut-être remarqué que la mise en cache peut être considérée comme un artefact « architectural » et doit donc être maîtrisée par tous les membres de l’équipe, depuis le développement jusqu’à l’administration.

Même si les personnes affectées au développement n’ont pas réellement à configurer le Dispatcher, elles doivent en connaître les concepts, en particulier les limites, pour s’assurer que leur code peut également être exploité par le Dispatcher.

Le Dispatcher n’améliore pas la vitesse du code par magie. C’est pourquoi les développeurs et développeuses doivent créer leurs composants en gardant le Dispatcher à l’esprit. Il est donc nécessaire de savoir comment il fonctionne.

Mise en cache du Dispatcher - Principes de base

Le Dispatcher en tant que mise en cache Http - Répartition de charge

Qu’est-ce que le Dispatcher et pourquoi s’appelle-t-il « Dispatcher » ?

Le Dispatcher est

  • Avant tout un cache

  • Un proxy inverse

  • Un module du serveur web Apache httpd, dotant la polyvalence d’Apache des fonctions associées à AEM et fonctionnant sans problème avec tous les autres modules Apache (tels que SSL ou même SSI, comme nous le verrons plus loin).

Aux prémices d’Internet, les sites pouvaient s’attendre à quelques centaines de visiteurs et visiteuses. La configuration d’un Dispatcher (ou répartiteur) « répartissait » ou équilibrait la charge des requêtes sur un certain nombre de serveurs de publication AEM, ce qui était généralement suffisant. Aujourd’hui, cependant, cette configuration n’est plus très souvent utilisée.

Nous verrons différentes manières de configurer les systèmes de Dispatcher et de publication plus loin dans cet article. Commençons par quelques bases de mise en cache http.

Fonctionnalités de base d’un cache de Dispatcher

Fonctionnalités de base d’un cache de Dispatcher

Les principes de base du Dispatcher sont expliqués ici. Le Dispatcher est un proxy inverse simple de mise en cache permettant de recevoir et de créer des requêtes HTTP. Un cycle de requête/réponse normal se présente comme suit :

  1. Une personne demande une page.
  2. Le Dispatcher vérifie s’il dispose déjà d’une version rendue de cette page. Supposons qu’il s’agisse de la toute première requête pour cette page et que le Dispatcher ne trouve pas de copie locale mise en cache.
  3. Le Dispatcher demande alors la page au système de publication.
  4. Sur le système de publication, la page est rendue par un JSP ou un modèle HTL.
  5. La page est renvoyée au Dispatcher.
  6. Le Dispatcher met la page en cache.
  7. Il renvoie la page au navigateur.
  8. Si la même page est demandée une seconde fois, elle peut être diffusée directement à partir du cache du Dispatcher sans avoir à la restituer à nouveau sur l’instance de publication. Les temps d’attente sont ainsi réduits pour les cycles utilisateur et CPU sur l’instance de publication.

La section précédente couvrait les « pages ». Mais le même schéma s’applique également à d’autres ressources telles que des images, des fichiers CSS, des téléchargements de fichiers PDF, etc.

Mettre en cache les données

Le module Dispatcher tire parti des fonctionnalités fournies par le serveur Apache d’hébergement. Les ressources telles que les pages HTML, les téléchargements et les images sont stockées sous la forme de fichiers simples dans le système de fichiers Apache. C’est aussi simple que ça.

Le nom de fichier s’inspire de l’URL de la ressource demandée. Si vous demandez un fichier /foo/bar.html, il est stocké sous /var/cache/docroot/foo/bar.html, par exemple.

En principe, si tous les fichiers sont mis en cache et donc stockés de manière statique dans le Dispatcher, vous pouvez arrêter le système de publication et le Dispatcher agira comme un simple serveur web. Il ne s’agit que de théorie. La vie réelle est plus compliquée. Vous ne pouvez pas tout mettre en cache, et le cache n’est jamais complètement « plein », car le nombre de ressources peut être infini en raison de la nature dynamique du processus de rendu. Le modèle de système de fichiers statique donne une idée approximative des fonctionnalités du Dispatcher. Et renseigne sur ses limites.

Structure des URL AEM et mappage du système de fichiers

Pour comprendre plus en détail le Dispatcher, examinons la structure d’un simple exemple d’URL. Prenons l’exemple ci-dessous :

http://domain.com/path/to/resource/pagename.selectors.html/path/suffix.ext?parameter=value&otherparameter=value#fragment

  • http indique le protocole.

  • domain.com est le nom de domaine.

  • path/to/resource est le chemin d’accès sous lequel la ressource est stockée dans CRX, puis dans le système de fichiers du serveur Apache.

À partir de là, les systèmes de fichiers AEM et Apache divergent.

Dans AEM,

  • pagename est le libellé des ressources.

  • selectors représente un certain nombre de sélecteurs utilisés dans Sling pour déterminer le mode de rendu de la ressource. Une URL peut avoir une infinité de sélecteurs. Ils sont séparées par un point. Une section de sélecteurs peut ressembler à « French.mobile.fancy », par exemple. Les sélecteurs ne doivent contenir que des lettres, des chiffres et des tirets.

  • html est le dernier des « sélecteurs » et est donc appelé extension. Dans AEM/Sling, il détermine également en partie le script de rendu.

  • path/suffix.ext est une expression de type chemin d’accès qui peut être un suffixe de l’URL. Elle peut être utilisée dans les scripts AEM pour contrôler davantage le rendu d’une ressource. Nous aborderons ce sujet dans une section dédiée ci-dessous. Pour l’instant, retenez que vous pouvez l’utiliser comme paramètre supplémentaire. Les suffixes doivent avoir une extension.

  • ?parameter=value&otherparameter=value est la section de requête de l’URL. Elle est utilisée pour transmettre des paramètres arbitraires à AEM. Les URL avec des paramètres ne peuvent pas être mises en cache et les paramètres doivent donc être limités aux cas où ils sont absolument nécessaires.

  • #fragment, la partie fragment d’une URL n’est pas transmise à AEM, elle est utilisée uniquement dans le navigateur : dans les frameworks JavaScript comme « paramètres de routage » ou pour accéder à une partie spécifique de la page.

Dans Apache (consultez le diagramme ci-dessous),

  • pagename.selectors.html est utilisé comme nom de fichier dans le système de fichiers du cache.

Si l’URL comporte un suffixe path/suffix.ext, alors

  • pagename.selectors.html est créé en tant que dossier.

  • path est un dossier dans le dossier pagename.selectors.html.

  • suffix.ext est un fichier dans le dossier path. Remarque : si le suffixe ne comporte pas d’extension, le fichier n’est pas mis en cache.

Structure du système de fichiers après obtention des URL du Dispatcher .

Structure du système de fichiers après obtention des URL du Dispatcher.

Limites de base

Le mappage entre une URL, la ressource et le nom de fichier est assez simple.

Vous avez peut-être remarqué quelques pièges, cependant :

  1. Les URL peuvent devenir longues à n’en plus finir. L’ajout de la partie « chemin » d’un emplacement /docroot sur le système de fichiers local peut facilement dépasser les limites de certains systèmes de fichiers. L’exécution du Dispatcher dans les systèmes de fichiers NTFS sous Windows présente son lot de difficultés. Linux reste toutefois la panacée.

  2. Les URL peuvent contenir des caractères spéciaux et des umlauts. En règle générale, le Dispatcher ne s’en soucie pas. Gardez toutefois à l’esprit que l’URL est interprétée à de nombreux endroits de votre application. Plutôt deux fois qu’une, nous avons constaté que le comportement erratique d’une application était dû à un morceau de code (personnalisé) rarement utilisé qui n’avait pas été testé suffisamment pour les caractères spéciaux. Évitez-les si vous le pouvez. S’ils sont indispensables, réalisez des tests minutieux.

  3. Dans CRX, les ressources contiennent des sous-ressources. Par exemple, une page comporte un certain nombre de sous-pages. À l’inverse des systèmes de fichiers, qui peuvent contenir des fichiers ou des dossiers.

Les URL sans extension ne sont pas mises en cache.

Les URL doivent toujours avoir une extension. Toutefois, vous pouvez fournir des URL sans extensions dans AEM. Ces URL ne seront pas mises en cache dans le Dispatcher.

Exemples

http://domain.com/home.html peut être mise en cache.

http://domain.com/home ne peut pas être mise en cache.

La même règle s’applique lorsque l’URL contient un suffixe. Le suffixe doit disposer d’une extension pour pouvoir être mis en cache.

Exemples

http://domain.com/home.html/path/suffix.html peut être mise en cache.

http://domain.com/home.html/path/suffix ne peut pas être mis en cache.

Vous vous demandez peut-être, que se passe-t-il si la partie ressource n’a pas d’extension, mais que le suffixe en a une ? Dans ce cas, l’URL n’a aucun suffixe. Prenons l’exemple suivant :

Exemple

http://domain.com/home/path/suffix.ext

/home/path/suffix est le chemin d’accès à la ressource… il n’y a donc aucun suffixe dans l’URL.

Conclusion

Ajoutez toujours des extensions au chemin et au suffixe. Certains grands manitous du référencement voient cela d’un mauvais œil, car votre classement dans les résultats de recherche diminuerait. Mais une page non mise en cache est très lente et classée encore plus bas.

Conflits de suffixes d’URL

Supposons que vous ayez deux URL valides :

http://domain.com/home.html

et

http://domain.com/home.html/suffix.html

AEM les reconnaît sans problème. Vous ne rencontreriez aucun problème sur votre ordinateur de développement local (sans Dispatcher). Pas plus que lors des tests UAT ou de chargement. Le problème auquel nous sommes confrontés est si subtil qu’il passe la plupart des tests. Cela pourrait devenir un souci important en cas d’activité élevée si vous êtes limité en temps sans accès au serveur ou sans ressource pour résoudre le problème. Nous y sommes allés…

Alors… quel est le problème ?

home.html dans un système de fichiers peut être un fichier ou un dossier. Pas les deux en même temps comme avec AEM.

Si vous demandez home.html en premier, il sera créé sous forme de fichier.

Les requêtes suivantes vers home.html/suffix.html renvoient des résultats valides, mais sous la forme de fichier ; home.html « bloque » la position dans le système de fichiers, home.html ne peut pas être créé une seconde fois en tant que dossier et, par conséquent, home.html/suffix.html n’est pas mis en cache.

Position de blocage des fichiers dans le système de fichiers empêchant la mise en cache des sous-ressources

Position de blocage des fichiers dans le système de fichiers empêchant la mise en cache des sous-ressources

Si vous effectuez l’opération d’une autre façon, commencez par demander home.html/suffix.html puis suffix.html sera d’abord mis en cache dans un dossier /home.html. Cependant, ce dossier est supprimé et remplacé par un fichier home.html lorsque vous demandez ultérieurement home.html comme ressource.

Supprimer une structure de chemin lorsqu’un parent est récupéré comme ressource

Supprimer une structure de chemin lorsqu’un parent est récupéré comme ressource

Ainsi, le résultat de ce qui est mis en cache est entièrement aléatoire et dépend de l’ordre des requêtes entrantes. Ce qui rend les choses encore plus compliquées, c’est qu’il y a habituellement plus d’un Dispatcher. Les performances, le taux d’accès et le comportement du cache peuvent varier d’un Dispatcher à l’autre. Si vous souhaitez savoir pourquoi votre site Web ne répond pas, vous devez vous assurer que vous consultez le bon Dispatcher avec l’ordre de mise en cache défectueux. Si vous vérifiez le Dispatcher qui, par chance, a un modèle de requête favorable, ce serait peine perdue de trouver le problème à résoudre.

Eviter les URL en conflit

Vous pouvez éviter les « URL en conflit », lorsqu’un nom de dossier et un nom de fichier « concourent » pour le même chemin d’accès dans le système de fichiers, lorsque vous utilisez une extension différente pour la ressource lorsque vous disposez d’un suffixe.

Exemple

  • http://domain.com/home.html

  • http://domain.com/home.dir/suffix.html

Les deux sont bien mises en cache,

Choisissez une extension dédiée « dir » pour une ressource lorsque vous demandez un suffixe ou que vous évitez de l’utiliser avec le suffixe. Il existe de rares cas où ces éléments sont utiles. Ces cas sont relativement simples à mettre en œuvre. Nous en reparlerons dans le prochain chapitre, lorsque nous aborderons l’invalidation et la purge du cache.

Requêtes impossibles à mettre en cache

Passons en revue rapidement le dernier chapitre et quelques autres exceptions. Le Dispatcher peut mettre en cache une URL si elle est configurée comme pouvant être mise en cache et s’il s’agit d’une requête GET. Elle ne peut pas être mise en cache sous l’une des conditions suivantes.

Requêtes pouvant être mises en cache

  • La requête est configurée pour pouvoir être mise en cache dans la configuration du Dispatcher.
  • La requête est une requête GET brute

Requêtes ou réponses impossibles à mettre en cache

  • Requête refusée par le cache de par sa configuration (chemin, modèle, type MIME)
  • Réponses qui renvoient un en-tête « Dispatcher: no-cache »
  • Réponse qui renvoie un en-tête « Cache-Control: no-cache|private »
  • Réponse qui renvoie un en-tête « Pragma: no-cache »
  • Requête avec paramètres de requête
  • URL sans extension
  • URL avec un suffixe qui ne comporte pas d’extension
  • Réponse qui renvoie un code d’état autre que 200
  • Requête POST