Quelles métriques pour mesurer l’expérience utilisateur?

L’expérience utilisateur est défini comme un concept apparu dans les années 2000 pour tenter de qualifier le résultat (bénéfice) et le ressenti de l’utilisateur (expérience) lors d’une manipulation (utilisation provisoire ou récurrente) d’un objet fonctionnel ou d’une interface homme-machine (source wikipedia).

C’est cette expérience utilisateur qui est au cœur de la stratégie de développement des grands noms du commerce sur internet. Lorsqu’on sait qu’un internaute s’impatiente à partir de 2 secondes d’attente, ou que le taux d’abandon augmente de 40% lorsque le chargement d’une page passe de une à cinq secondes on comprend pourquoi ces sociétés investissent beaucoup de moyens dans l’optimisation de leurs sites web.

Dans ce contexte, le temps de chargement d’une page web revêt une attention toute particulière que les experts essayent de mesurer efficacement. Deux aspects sont primordiaux dans l’analyse de l’expérience utilisateur: Le contenu de la page doit commencer à s’afficher très rapidement pour permettre à l’utilisateur d’interagir avec l’application, et le chargement de la partie visible de la page doit être privilégié. La partie en dessous de la ligne de flottaison est moins importante du fait qu’elle n’est pas immédiatement visible par l’utilisateur. C’est ce sentiment d’interactivité avec l’application qui va satisfaire ou non l’internaute.

« Page load time »

La mesure la plus ancienne permettant d’analyser la vitesse de chargement d’une page est fournit par la méthode window.onload(). Cette métrique identifie le temps nécessaire au chargement, par le navigateur, de toutes les ressources de la page. Cette méthode, largement utilisée par le passé, n’est plus adaptée car un grand nombre de sites sont devenus entièrement dynamique et les ressources des pages sont chargées de façon asynchrone. De fait il est possible que cette métrique soit inférieure (ou supérieure) au temps nécessaire pour afficher le contenu de la page.

Steve Souders, un des experts mondiaux de la performance, rapportait en 2013 que certains sites internet pouvaient s’afficher très rapidement mais cet indicateur windows.onload révélait que le temps de chargement des pages étaient lent. Pourquoi? Parce que tout simplement le contenu au dessus de la ligne de flottaison de la page s’affichait rapidement et que le reste du contenu de la page prenait un peu plus de temps à se charger.

« Start render »

Certains sites tel que webpagetest fournissent un indicateur « start render » qui mesure le moment ou le contenu de la page commence à apparaître dans le navigateur. C’est un indicateur intéressant car il indique le moment à partir duquel l’internaute commence à voir le résultat de son action. Mais il reste insuffisant car il n’indique pas quand l’internaute peut interagir avec le site. Ce n’est donc pas non plus la métrique idéale pour mesurer cette expérience utilisateur.

« Speed index »

Le « speed index » prend en compte la progression du chargement de la partie visible de la page et calcule un score global mesurant la rapidité avec laquelle le contenu est affiché. Pour calculer cette métrique WebPagetest utilisait un algorithme qui analysait une capture vidéo du chargement de la page à raison de 10 frames par seconde, plus récemment WebPagetest a implémenté un procédé d’analyse basé sur des événements émis par le navigateur lors du rendu de la page. Le détail du calcul du « speed index » est décrit sur le site WebPageTest  (https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index).
Ce score mesure donc la vitesse à laquelle la partie de la page se situant au dessus de la ligne de flottaison est affichée : plus le score est bas, plus la page s’est affichée rapidement.
Cette métrique illustre plutôt bien la qualité de l’expérience utilisateur mais elle n’est disponible qu’au travers de WebPageTest.

« Time to First Contentful Paint (TTFCP) »

Plus récemment les métriques TTFCP « Time to First Contentful Paint » et TTFP « Time to First Paint » exposent des informations qui peuvent permettre aux développeurs de mieux comprendre la performance du chargement des sites internet, et mesurer l’expérience utilisateur. Ces nouveaux indicateurs sont disponibles au travers de l’API « Paint timing API » du navigateur Chrome.

Solutions spécifiques

D’autres initiatives commencent à voir le jour telles que Hero Rendering Times disponible dans la solution SpeedCurve. Cette solution part de l’idée qu’il faut pouvoir spécifier ce qui doit être mesuré dans une page, et que tous les éléments d’une page n’ont pas la même importance du point de vue de l’internaute. Par exemple l’affichage d’un encart publicitaire au dessus de la ligne de flottaison a t-il la même importance que les autres informations présentées sur la page?

https://www.jperf.com

Publicités
Publié dans Uncategorized | Laisser un commentaire

Comment planter un chantier d’amélioration des performances

Il existe de nombreuses façons de faire échouer un chantier d’amélioration des performances, mais il en existe une qui relève du sponsoring.

L’amélioration des performance relève des exigences non fonctionnelles et ces dernières sont souvent sont reléguées au second plan dans les phases de qualification d’un logiciel.

De fait les problématiques de performance sont étudiées très tardivement dans le cycle de développement. Malheureusement à ce stade, la solution à ces problèmes de performance peuvent conduire à remettre en cause l’architecture du logiciel.

Pour reprioriser l’analyse des performances il est nécessaire que cette activité soit portée par un sponsor. Une personne qui peut prendre des décisions et impulser des actions, mobiliser des équipes, organiser des « war rooms »… Une personne qui travaille en collaboration intelligente avec ses propres équipes d’experts. Ce sponsor  doit avoir confiance dans les compétences de ces équipes, il doit se reposer sur celles ci pour appuyer les prises de décisions, les choix, les orientations. Lorsque cela s’avère nécessaire, il doit également pouvoir exercer une pression sur les prestataires afin qu’ils prennent en compte dans le plan de développement, les actions d’amélioration des performances qui ont été identifiées par ses équipes techniques.

Imaginez un manager décisionnaire qui ne consulte pas ses équipes et qui négocie, avec un acteur du projet, des actions techniques qui n’ont pas reçues l’aval des experts de l’entreprise. Est ce un sponsor?

Sans sponsor décisionnaire proche de ses consultants, il est très difficile de faire appliquer rapidement des préconisations d’amélioration des performances qui n’ont pas de valeurs ajoutées d’un point de vue fonctionnel et qui peuvent avoir un impact significatif sur le développement du produit final.

Le risque est donc de faire durer cette activité dans le temps, d’entrer dans des opérations de suivi d’avancement très chronophages.

http://www.jperf.com

Publié dans performance | Laisser un commentaire

Performance – TOP 5 – Granularité des services

Parmi les problèmes de performance auxquels j’ai été confronté, il y a ceux qui relèvent de la granularité des services dans une architecture SOA.

Cette catégorie regroupe beaucoup de mauvaises pratiques dont ont les impacts ne sont pas toujours faciles à évaluer mais qui ont nécessairement une influence sur la capacité à monter en charge d’une application.
On peut citer par exemple les problèmes relatifs à des invocations excessives de la couche de service généralement liés à une granularité trop faible des services. L’application cliente doit dans ce cas gérer une multitude d’invocations de service pour réaliser l’action requise.
Parfois c’est tout simplement une mauvaise connaissance de l’application cliente ou une mauvaise gestion du contexte d’exécution qui conduit les développeurs à multiplier les invocations aux mêmes services. Ce dernier cas de figure peut être rencontré sur des applications ou l’équipe de développement est plus ou moins livrée à elle même, sans réel leader qui assurerait une cohérence d’ensemble du développement. Ces problèmes peuvent également être liés à une mauvaise connaissance ou une documentation inadaptée du fonctionnement des services.

Parmi les solutions permettant d’éradiquer les problèmes de performance liés à la granularité des services nous pouvons évoquer les pistes suivantes:

  • S’assurer du bon niveau de granularité des services. Une granularité trop faible conduit à un nombre excessif d’appel de service tandis qu’une granularité trop forte conduit à la multiplication des services ayant des comportements similaires;
  • Profiler l’application pour s’assurer que l’application n’exécute pas un nombre excessif d’appel de service.
  • Rationaliser les appels de service pour ne pas invoquer plusieurs fois les mêmes services.

http://www.jperf.com

Publié dans performance | Laisser un commentaire

Améliorer les performances d’une application web (1er volet)

Savez vous que 47% des internautes s’attendent à ce qu’une page web s’affiche en moins de deux secondes et que 40% des gens vont fermer une page si elle met plus de trois secondes à se charger?  Sur un site de eCommerce le temps d’affichage d’une page a un impact direct sur le taux d’abandon d’un panier.

Dans ce contexte, on comprend pourquoi la performance d’un site web puisse requérir une attention toute particulière. Nous pouvons également avoir la même réflexion pour un site web interne ou un extranet ouvert aux partenaires.

Dans le processus d’amélioration des performances d’une application web on s’intéresse à la fois à ce qui se passe sur le serveur mais également dans la couche cliente (le navigateur). Dans ce premier volet, nous allons nous intéresser plus particulièrement à cette couche cliente : le navigateur.

Il y a de nombreuses technologies qui peuvent être utilisées dans cette couche qui peuvent donner lieu à une attention particulière (applet, flex…), mais nous limiterons notre sujet aux simples requêtes HTTP.

Comment réduire le temps de chargement d’une page web?

1er conseil : Réduire le nombre de requêtes

Cette technique vise à réduire le nombre de requêtes exécutées pour afficher une page. Il s’agit de l’approche la plus importante pour améliorer les performances d’affichage des pages pour les visiteurs qui accèdent au site pour la première fois.

Elle part du constat qu’une grande partie du temps consacré à l’affichage d’une page, ressenti par l’utilisateur d’un site, est passée sur le navigateur et que la majeure partie de ce temps est lié au téléchargement de tous les composants de la page: images, feuilles de style, scripts…

Cette approche met en jeu des techniques permettant de réduire le nombre de ressources à charger. Elle s’appuie notamment sur des solutions de fusion des scripts et des feuilles de style, et de combinaison des images dans un seule image (sprite).
Dans le cas du sprite, c’est à dire du regroupement des images dans une seule image, l’affichage d’une image en particulier est réalisée au travers de la définition de classes CSS qui déclarent notamment une propriété background-position qui précise la position du coin supérieur gauche de l’image que l’on veut afficher. Il faut également définir le fichier image via la propriété background-image ainsi que la taille de l’image à afficher avec les propriétés width et height.

2 ème conseil : Utiliser un CDN Content Delivery Network ou domain Sharding

Les navigateurs limitent volontairement le nombre de requêtes simultanées sur un domaine internet dans le but de ne pas surcharger les serveurs. Les anciens navigateurs autorisaient 2 connexions simultanées (IE7) tandis que les versions plus récentes permettent de réaliser entre 6 et 8 connexions simultanées. Ce dispositif n’empêche pas qu’un site internet chargeant un grand nombre de ressources statiques telles que des images, des scripts, des feuilles de style soit pénalisé par ces limites.

Il existe 2 techniques distinctes permettant d’améliorer le temps de chargement de ces ressources.

Le domain sharding est une technique qui consiste à charger les ressources statiques à partir de sous domaine. Cette technique permet donc de multiplier le nombre de requêtes simultanées par le nombre de sous domaine. L’approche consiste donc à distribuer les ressources entre différents domaines de façon à dépasser les limitations imposées par les navigateurs.
L’inconvénient est que chaque sous domaine nécessite de mettre en oeuvre une résolution de domaine qui peut ajouter un temps de latence supplémentaire. Sur les mobiles, la résolution DNS est également plus longue que pour les connexions dites conventionnelles.

La résolution DNS est le procédé de conversion d’un nom de domaine (par exemple google.com) en une adresse IP.

Il faut toutefois garder à l’esprit que cette technique peut être contre productive dans le cas ou le site web réalise peu de requêtes vers des ressources statiques. Notez également que le protocole HTTP/2.0 rend cette pratique est obsolète.

Le CDN (Content Delivery Network) est un réseau de serveurs distribués sur la planète qui délivre du contenu aux utilisateurs en fonction de la situation géographique des visiteurs. Cette approche consiste donc à distribuer les ressources sur un réseau de serveurs distribués dans le monde, et peut être intéressante pour des sites qui ont une audience internationale. Plusieurs sociétés se répartissent les parts de marché dans ce domaine citons par exemple Akamai, Amazon CloudFront….

3ème conseil : Utiliser le cache des navigateurs

L’utilisation d’un cache pour les ressources statiques a un impact majeur sur les performances et l’expérience utilisateur.  En effet bien que cette technique n’ait aucune incidence lors de la première visite d’un internaute sur la page de votre site, elle permet de réduire l’utilisation de la bande passante et le niveau de sollicitation des serveurs mais également améliore sensiblement le temps de chargement des pages lors des visites successives.
Bien entendu, l’utilisation du cache doit être réservée aux ressources statiques telles que les images, les feuilles de style, les scripts et ne doit surtout pas être utilisée pour gérer du contenu dynamique.
L’idée est de paramétrer l’entête HTTP « expires » de façon à ce que la ressource soit mise en cache sur le navigateur pendant la période déclarée. Lorsque la ressource est expirée (ou si l’utilisateur demande un rafraîchissement de la page « soft-refresh »), si les entêtes HTTP Etag ou Last-Modified sont présents sur la ressource, le navigateur lance une requête conditionnelle avec les entêtes If-None-Match ou If-Modified-Since.
Si le serveur répond avec un status HTTP 304 (Not modified) avec les entêtes relatives à la mise en cache de la ressource, le navigateur gardera la ressource dans le cache et modifiera la date d’expiration conformément aux informations renvoyées par le serveur.
La ressource est, bien entendu servie, par le cache du navigateur.

Pour les ressources statiques mises en cache qui peuvent être modifiées périodiquement, il existe des techniques de gestion de version qui permettent de prendre en compte la modification en forçant le navigateur à charger la nouvelle ressource.

4ème conseil : Compresser les contenus

Le temps de chargement d’une ressource dépend en particulier de la taille du contenu. Un navigateur prendra plus de temps pour charger une ressource de 100 Ko qu’une ressource de 10 Ko 😉 . Cette technique répond à cette exigence de réduction de la taille des ressources en utilisant une technique de compression.
Les ressources textuelles sont principalement visées par cette approche : les documents HTML, les feuilles de style, les scripts…

5ème conseil : Déplacer les scripts à la fin de la page

Cette technique consiste à déclarer les scripts juste avant la fermeture du tag BODY de la page. En effet, l’une des caractéristiques des scripts est qu’ils s’exécutent à l’emplacement exact où ils sont insérés dans le document et de fait, ils bloquent la construction du DOM (Document Object Modèle) et retarde l’affichage initial de la page. Autrement dit, un script déclaré au milieu du contenu d’une page bloque l’affichage du reste de la page tant que le script n’est pas exécuté. Cela peut provoquer des situations de page blanche, ou des effets visuels disgracieux ou l’utilisateur voit le chargement partiel de la page puis attend le rendu complet.

Plus techniquement, lorsque l’analyseur HTML rencontre une balise de script, il suspend le processus de construction du DOM, puis cède le contrôle au moteur JavaScript. Lorsque celui-ci a fini de s’exécuter, le navigateur reprend sa tâche au point où il l’a laissée, puis reprend la construction du DOM. Pourquoi la construction du DOM est-elle interrompue? Tout simplement car le script peut modifier le DOM et le CSSOM (représentation objet d’une feuille de style) qui sont tout deux nécessaires à la construction du rendu de la page.

Par ailleurs, si le navigateur n’a pas fini de construire le CSSOM au moment ou un script peut être exécuté, il retardera l’exécution du script jusqu’à ce que le CSSOM soit construit.

Il est donc nécessaire de charger les feuilles de style le plus tôt possible dans le processus de construction de la page. En fait, cette étape fait appel à une autre notion « le chemin critique du rendu » que nous aborderons dans un autre volet.

Le chemin critique du rendu fait appel à l’optimisation du schéma de dépendance entre HTML, CSS et JavaScript et, plus particulièrement, il s’agit d’améliorer les performances de sorte que le navigateur charge très rapidement tous les éléments graphiques qui sont visibles immédiatement afin que l’utilisateur ait une sensation d’instantanéité. Les éléments non visibles sont chargés d’une façon imperceptible pour l’utilisateur.

Notons simplement à ce stade qu’il existe des attributs de la balise script qui permettent de rendre un script non bloquant.

  • defer : différer l’exécution à la fin du chargement du document.
  • async : charger/exécuter les scripts de façon asynchrone (par un autre thread).

Nous reviendrons plus précisément, dans un prochain volet, sur les mécanismes mis en oeuvre lors du chargement des scripts.

6ème conseil : Externaliser les ressources

Les ressources de type feuille de style et script devraient être externalisées dans des fichiers de façon à bénéficier de l’utilisation du cache du navigateur.

7ème conseil : Réduire l’impact de la résolution DNS

Pour réduire l’impact de la résolution DNS, il est nécessaire d’utiliser la directive HTTP keep-alive et rationaliser l’utilisation des domaines différents.

La directive Keep-alive est un dispositif permettant d’utiliser une simple connexion TCP pour envoyer et recevoir de multiples requêtes et réponses.
Elle s’oppose à un fonctionnement ou chaque requête nécessite l’ouverture et la fermeture d’une connexion TCP. Avec le protocole HTTP/1.1 toutes les connexions sont considérées persistantes par défaut.

8ème conseil : Minifier les scripts

Cette opération consiste à réduire la taille des scripts en supprimant tous les caractères non indispensables (commentaires, espaces inutiles…). Elle peut venir en complément de la technique de compression pour réduire la taille de la ressource.

En synthèse

L’application de ces premières mesures devraient vous permettre d’améliorer le ressenti de l’utilisateur. Dans un prochain volet, nous nous intéresserons à la notion de chemin critique du rendu et nous entrerons plus en détails sur l’impact des scripts sur la performance de l’affichage des pages.

http://www.jperf.com

Publié dans performance | Laisser un commentaire

Qu’est ce que le PACING?

Dans le domaine des tests de performance, il s’agit du temps minimum entre chaque itération d’un scénario de test.

Qu’est ce qu’une itération?

Imaginez que vous recherchiez un objet sur un site d’annonces en ligne. Votre scénario de test pourrait consister en un accès à la page d’accueil du site, le choix de critères de sélection, le parcourt de la liste des objets correspondants à vos critères, et la consultation des annonces les plus intéressantes. Malheureusement vous n’avez rien trouvé et vous quittez le site en fermant simplement votre navigateur. L’exécution de ce scénario une seule fois représente une itération.

Le pacing correspond donc au temps séparant deux exécutions d’un scénario par un même utilisateur virtuel. Il peut être égal ou supérieur au temps d’exécution du scénario. Dans le cas ou il est supérieur, un délai est ajouté à la fin de l’exécution de l’itération avant de commencer l’itération suivante. Si le pacing est inférieur ou égal au temps d’exécution du scénario, l’itération suivante débute immédiatement après la fin de la précédente.

A quoi cela sert il?

Ce mécanisme permet de réaliser des tests de performance avec un taux constant de transactions/requêtes. De fait, lorsque le pacing est calculé correctement, à chaque itération tous les utilisateurs virtuels commencent un nouveau scénario en même temps. Personnellement j’utilise assez peu cette méthode de simulation de charge qui peut produire des graphes d’utilisation des ressources en dents de scie puisque à la fin des itérations tous les utilisateurs virtuels attendent quelques secondes avant de démarrer une nouvelle itération.

http://www.jperf.com

 

Publié dans performance, Uncategorized | Tagué , | Laisser un commentaire

Hibernate: Comment tracer les requêtes SQL et les paramètres des requêtes

Cet article est davantage un pense bête personnel.

Ces deux articles expliquent parfaitement les bonnes pratiques en matière de debugage des requêtes SQL et la manière de les mettre en oeuvre.

Mieux vaut éviter d’utiliser la propriété show_sql et préférer une configuration des logs (org.hibernate.SQL, org.hibernate.type.descriptor.sql …).

http://www.thoughts-on-java.org/hibernate-logging-guide/

http://docs.jboss.org/hibernate/orm/4.3/topical/html/logging/Logging.html

Cependant vous pouvez rencontrer des problèmes de mise en oeuvre si vous utilisez une librairie de log telle que SLF4J. Pourquoi ? Parce que Hibernate (depuis la version 4) utilise un « bridge » pour ne pas être dépendant d’une librairie de log particulière. Ce bridge teste les API disponibles dans le classpath selon un ordre précis. Donc assurez vous bien que les librairies tierces que vous avez intégrées dans votre projet n’ont pas de dépendance avec une API de log.

Dans un projet maven, il suffit d’exécuter la tâche dependency-tree qui liste l’ensemble des dépendance de votre projet. Si vous trouvez une dépendance avec une autre librairie de log, il faudra exclure cette dépendance en intègrant une section exclusion dans le noeud dependency.

Par exemple pour exclure une dépendance avec la librairie log4j.

<dependency>
...
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>

 

Publié dans tech notes | Tagué | Laisser un commentaire

Terminaison SSL avec Apache2/Tomcat/Shiro

Cet article est une note technique permettant de mettre en oeuvre une terminaison SSL dans un environnement Apache2 / Tomcat / Shiro+Spring.

Apache Shiro est une librairie permettant de mettre en oeuvre des fonctions de sécurisation d’une application web. Elle présente approximativement les mêmes fonctionnalités que la solution Spring security. On peut noter toutefois qu’elle permet de sécuriser également des applications standalone, qu’elle intègre nativement la fonction « remember me », etc.

Quelle est précisément la problématique?

Dans une infrastructure de production, l’accès à certaines ressources peuvent être protégées par un protocole sécuritaire (SSL) mais les autres composants de l’infrastructure qui sont déployés dans une zone de confiance n’ont pas vocation à utiliser ce protocole qui ajoute un « overhead » qui n’est pas nécessaire dès lors que les communications sont réputées fiables.

Dans cet article, je détaillerai la mise en oeuvre de ce mécanisme (terminaison SSL) dans un contexte Shiro / spring qui présente une petite difficulté.

La mise en oeuvre de Shiro avec Spring n’est pas l’objet de cette note, cependant voici un extrait de la configuration permettant d’activer Shiro et de configurer l’utilisation de SSL pour sécuriser l’accès à certaines ressources de l’application. C’est le filtre Shiro qui porte cette configuration.


<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/connexion" />
<property name="filters">
<util:map>
<entry key="authc">
<bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter" />
</entry>
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
/javax.faces.resource/** = anon
/connexion = ssl[${ssl.port}],authc
/moncompte = user
/** = anon
</value>
</property>
</bean>

Nous notons simplement que l’utilisation du filtre PassThruAuthenticationFilter est intéressant car il permet de mettre en place une logique de validation spécifique à l’application. Ce filtre n’autorise l’accès aux ressources que si l’utilisateur est authentifié ou lorsque la ressource demandée correspond à la page d’authentification. Dans cette configuration la ressource identifée par « /connexion » nécessite la mise en oeuvre du protocole SSL. Cette vérification est assurée par la déclaration du filtre SSL (ssl[${ssl.port}]) implémentée par défaut par la classe org.apache.shiro.web.filter.authz.SslFilter.
L’accès à la ressource « /moncompte » est protégée par le filtre UserFilter qui par défaut vérifie que l’utilisateur est connu soit parce qu’il est authentifié soit parce que la fonction « remember me » permet d’identifier l’utilisateur.

Avec cette configuration, si l’utilisateur n’est pas identifié et essaye d’accéder à la ressource « /moncompte », il va être automatiquement redirigé vers la page de login protégée par le protocole SSL. Cependant on souhaite mettre en place une terminaison SSL au niveau du reverse proxy Apache, mais on veut également s’assurer que la requête d’authentification est sécurisée. Or que fait le filtre SSL de Shiro? Il vérifie que la requête utilise le port SSL configuré par la variable ${ssl.port}, et que la requête est sécurisée. Shiro utilise notamment la méthode ServletRequest.isSecure() pour vérifier que la requête est effectivement sécurisée.

Si la configuration du reverse proxy redirige uniquement les hôtes virtuels déclarés pour les protocoles (http et https) vers un port non sécurisé d’un serveur Tomcat, et que l’un de ces critères n’est pas respecté, les mécanismes de redirection mis en jeu provoquent une erreur HTTP 310 « Too many Redirects ».

Un des moyens permettant de mettre en place la terminaison SSL et d’indiquer à la librairie que la requête d’authentification est effectivement sécurisée, consiste à créer une entête HTTP spécifique indiquant que le reverse proxy a détecté l’utilisation d’un protocole sécurisé et de configurer Tomcat afin qu’il interprète cet entête et intègre ces informations dans le contenu de la requête.

Pour mettre en place cette logique, il est nécessaire :

  • sur le reverse proxy
    Activer le module header (sudo a2enmod headers);
    Mettre en place les directives d’écriture du header « X-Forwarded-Proto » sur chaque hôte virtuel;
    Par exemple pour un serveur Tomcat écoutant à l’adresse localhost:9090

    <VirtualHost *:80>
    ServerName www.mondomaine.com
    ServerAlias www.mondomaine.com
    ServerAdmin webmaster@mondomaine.com
    <span style="color: #ffcc00;">RequestHeader set X-Forwarded-Proto "http"</span>
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass / http://localhost:9090/
    ProxyPassReverse / http://localhost:9090/
    ....
    <VirtualHost *:443>
    ServerName www.mondomaine.com
    ServerAlias www.mondomaine.com
    ServerAdmin webmaster@test.mondomaine.com
    <span style="color: #ffcc00;">RequestHeader set X-Forwarded-Proto "https"</span>
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass / http://localhost:9090/
    ProxyPassReverse / http://localhost:9090/
    ...
    
  • Sur le serveur Tomcat
    Définir une valve dans la configuration du serveur Tomcat qui permet d’interpréter cet entête HTTP.
    Par exemple:

    <Valve>
    className="org.apache.catalina.valves.RemoteIpValve"
    protocolHeader="x-forwarded-proto"
    protocolHeaderHttpsValue="https"
    httpServerPort="80"
    httpsServerPort="443"
    />
    

    Ces paramètres indiquent notamment :
    « protocolHeader » le nom de l’entête HTTP qui désigne la nature du protocole utilisé. Dans cet article l’entête « x-forwarded-proto » porte cette définition;
    « protocolHeaderHttpsValue » la valeur de l’entête « protocolHeader » qui identifie que le protocole est sécurisé;
    ainsi que d’autres attributs dont vous pouvez avoir besoin qui sont décrits dans la documentation officielle (https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html).

Une fois ces modifications réalisées et les serveurs redémarrés, l’erreur HTTP 310 « Too many Redirects » que nous rencontrions précédemment disparaît, et la terminaison SSL sur le reverse proxy est opérationnelle.

http://www.jperf.com

Publié dans tech notes | Tagué , , , , | Laisser un commentaire