Techniques pour améliorer les performances d’une application web (Partie 2)

Utilisation du cache

En grande majorité, les pages servies par un serveur sont les mêmes pour la plupart des connections successives de clients. L'utilisation de cache consiste à garder en mémoire des copies des pages servies (ou des portions de pages) que ce soit coté client ou serveur.

Utilisation du cache coté serveur.

L'utilisation du cache coté serveur a un grand impacte sur les performances d'une application web. L'élaboration des pages est une activité qui consomme beaucoup de ressources et de temps. Cependant, la page servie pour un client demeure la même pour un autre et il est inutile de l'élaborer une autre fois.

La plupart des serveurs actuels présentent un mécanisme de cache pour les ressources statiques. Cependant, la plupart des applications web actuelles servent des contenus dynamiques. Un contenu dynamique peut être considéré comme statique sur un laps de temps bien déterminé, et la mise en cache des ces pages dynamiques peut améliorer les performances d'une application web.

Les outils Open Source utilisés dans la communauté Java sont multiples. Après étude, nous avons fixé le choix sur OS-Cache (V 2.4.1) et Ehcache (V 1.6).

Ces deux solutions sont performantes et très répandues pour les applications web. Sur les exemples qu'on a testés, les performances sont bien visibles et le temps peut être divisé par 25 (passage de 1s,45 à 130ms). Sur ces exemples, on note un léger avantage pour OS-Cache concernant les résultats et performances enregistrés.

En général, la plupart des benchmarks sur Internet donne l'avantage à Ehcache face à OS-Cache. Ehcache est plus complet qu’OS-Cache. En effet Ehcache définit plus de stratégies de gestion de la mémoire, supporte la réplication synchrone et asynchrone et il est plus extensible. La manipulation des fragments dynamiques des pages JSP se fait grâce soit à des filtres prédéfinis, soit par des filtres qu'il faut définir en code Java, ce qui représente un véritable inconvénient.

OS-Cache est plus adapté aux applications Java EE vu qu'il définit une librairie de tags qui facilitent la tache et permettent d'avoir un contrôle presque total de la mise en cache des fragments et portions dynamiques qui peuvent être considérés valides pendant une période de temps. Ainsi, on peut même anticiper les actions et les requêtes des clients et garder toujours en mémoire des résultats rafraichis au fur et à mesure.

La montée en compétence concernant les pages JSP est plus rapide et plus simple pour OS-Cache que pour Ehcache vu que le support et la documentation des dernières versions de ce dernier est payante.

Dans ce qui suit, on présente une démonstration simple de l'installation et l'utilisation d’OS-Cache.

Installation

L'installation d’OS-Cache 2.4.1 est simple. Il suffit d'ajouter le jar oscache-2.4.1.jar et si nécessaire le jar commons-logging.jar au projet. Il aussi configurer le fichier oscache.properties et l'ajouter au sous dossier classes du dossier WEB-INF. Ce fichier contient toutes les rubriques nécessaires pour la configuration de cette API. Voici un résumé de ces paramètres:

· cache.memory : utiliser ou non la mémoire pour la mise en cache (true ou false)

· cache.key : clé du cache pour l'application

· cache.use.host.domain.in.key : utiliser ou non les noms de domaine dans la clé (true ou false)

· cache.event.listeners : Intercepteur des liste des événements (cache, hits, miss, statistiques...)

· cache.persistence.class : classe de persistance des données.

· cache.persistence.overflow.only : utiliser toujours ou non la persistance dans le cas d'un dépassement (true ou false)

· cache.path : chemin du cache sur disque

· cache.algorithm : algorithme pour le cache (LRU, FIFO, Unlimited)

· cache.blocking : gestion de la concurrence sur l'accès d'une ressource cachée (true ou false)

· cache.capacity : taille du cache en nombre d'objets

· cache.unlimited.disk : taille limitée du cache sur disque (true ou false)

· cache.cluster.jms.topic.factory : propriétés de JMS pour le clustering

· cache.cluster.jms.topic.name : propriétés de JMS pour le clustering

· cache.cluster.jms.node.name : propriétés de JMS pour le clustering

Pour plus de détails, référer au fichier oscache.properties original.

Voici un exemple de configuration minimale:

cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JMSBroadcastingListener

cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener

cache.path=c:\TestPROJET\cache

cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache

cache.capacity=1000

Utilisation

OS-Cache supporte la mise en cache dans un contexte session ou application. Pour utiliser la taglib d'OS-Cache 2.4.1 il faut ajouter l'Uri:

<%@ taglib uri="http://www.opensymphony.com/oscache" prefix="cache" %>

Ensuite, on peut manipuler le cache grâce aux tags suivants:

· <cache:cache></cache:cache>

C'est la balise de base. Le bloc entouré par ces deux tags sera caché. Un bloc caché n'est plus valide s'il dépasse la durée spécifié dans le tag, ou si le contexte (application ou session) du cache est rafraichi.

La liste d'attributs de cette balise est:

Ø key : identifiant unique pour le cache

Ø scope : portée du cache.

Ø time : durée de validité en seconde du cache.

Ø Duration : Alternative à time, spécifiée avec un format.

Ø cron : expression qui détermine quand est-ce que le cache est expiré

Ø refresh : cache rafraichie ou non si elle est expirée.

Ø groups : groupes auxquels le cache appartient (utile lors d'une manipilation groupée)

Ø language : utilisé pour des sites multi-langues

Ø refreshpolicyclass : permet de spécifier une classe qui détermine le mécanisme d’expiration d’une ressource.

· <cache:usecached />

Cette balise permet d'utiliser un contenu caché

· <cache:flush/>

Cette balise permet de rafraichir un contenu caché.

· <cache:addgroup /> et <cache:addgroups />

Ces deux balises permettent d'ajouter des groupes.

Voici un exemple très simple de l’utilisation de cette bibliothèque de balises:


<cache:cache key="foo" scope="application" time="10000">
<%
try {

ApplicationContext context = ApplicationContextHolder.getContext();
ClientDao clientdao = (ClientDao) context.getBean("ClientDao");
List list = clientdao.getAllClients();
out.print("<BR><BR> Le nombre de clients est :" + list.size() + "<BR><BR>");
} catch (Exception e) {
out.print("<BR><BR> Exception, essai de lire à partir de la cache </<BR><BR>");%>
<cache:usecached />
<%
}
}
%>
</cache:cache>

Figure 7. Exemple avec OS-Cache taglibs 2.4.1

Dans cet exemple on met en cache la récupération du contexte de l'application et la liste des clients. Cette mise en cache a deux avantage, tout d'abord, elle minimise le temps de réponse, en plus, si la connexion à la base de données est interrompue, on peut toujours renvoyer le résultat en cache.


Image Non Disponible!

Figure 8. Filtres pour les servlets

Pour les servlets, OS-Cache définit des filtres pour les mettre en cache. En plus il peut être utilisé dans des classes java et mettre en cache des POJO.

L'inconvénient d'OS-Cache est qu'i ne gère pas la réplication des données. En plus, il ne gère pas des pages extérieurs au serveur. Ainsi, il ne peut donc pas être utilisé dans un contexte d’agrégation de ressources hétérogènes, provenant de différents serveurs, ou même de différentes applications d’un même serveur.

Cache Coté Client

Le cache coté client est très importante, vu qu'il permet d'une part de minimiser le temps de chargement, mais aussi qu’il consomme moins de bande passante. Lorsque le client demande une ressource qui a été déjà demandée, le navigateur demande au serveur si la ressource est encore valide. Si c'est le cas, le serveur retourne une réponse avec le code 304, et le navigateur sert la ressource mise en cache.

Deux techniques de cache coté client existent:

· Cache avec expiration : Ce mécanisme consiste à attribuer une durée après laquelle la page cachée dans la mémoire du navigateur devient obsolète.

· Cache avec validation : L'idée est d'attribuer à une page un identifiant unique ou Etag. Chaque fois que le client demande une ressource déjà visitée, le navigateur envoie une requête conditionnelle avec comme condition la correspondance Etag. Si le serveur reconnaît l’Etag il retourne 304 comme réponse, sinon il renvoie la page avec le nouveau Etag.

Le premier mécanisme ne nécessite pas des requêtes au serveur. Le deuxième mécanisme consomme plus la bande passante que le premier, mais la validation des pages est plus stricte, et les pages sont toujours à jour.

La manipulation des Etag est plus adaptée aux contenus dynamiques, mais il faut faire attention aux cas où l'application est répartie sur plusieurs serveurs. Dans ce cas il faut bien choisir la définition des Etags, sinon on pourra ralentir le chargement des pages. Par exemple Apache définit par défaut un Etag comme inode_size_time. Dans le cas d'une application répartie, une page aura plusieurs représentations, et une page cachée dans le navigateur, peut être ne pas détectée.

Tomcat permet de cacher les pages statistiques. Pour les pages dynamiques, il suffit d'ajouter aux en-têtes de la réponse un Etag qui permet d'identifier la ressource d'une manière unique. La difficulté ici réside dans le choix de l'identifiant qui correspond à une représentation de la page et qui ne change que si le contexte change.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.