La prise en charge du push serveur HTTP/2 est également incluse dans NGINX Plus R15 .
Nous sommes ravis d'annoncer que NGINX 1.13.9 , publié le 20 février 2018 , inclut la prise en charge du push serveur HTTP/2. Pour les utilisateurs de NGINX Plus, la prise en charge du push serveur HTTP/2 sera incluse dans la prochaine version NGINX Plus R15 , prévue pour avril 2018.
Le push serveur, tel que défini dans la spécification HTTP/2, permet à un serveur d’envoyer de façon anticipée des ressources à un client distant, en prévoyant que vous pourriez bientôt en faire la demande. Ainsi, vous pouvez réduire le nombre d’aller-retours réseau (RTT – le temps nécessaire pour une requête et sa réponse) lors du chargement d’une page d’un RTT ou plus, et bénéficier d’une réponse plus rapide.
Le push serveur sert à préparer un client avec les feuilles de style, images et autres ressources dont il aura besoin pour afficher une page web. Veillez à ne pousser que les ressources indispensables ; évitez d’envoyer celles que le client a probablement déjà en cache.
Dans cet article de blog, je décris :
de nghttp
)Lien
Pour envoyer des ressources avec le chargement d'une page, utilisez la directive http2_push
de la manière suivante :
server { # Assurez-vous que HTTP/2 est activé pour le serveur listen 443 ssl http2 ; ssl_certificate ssl/certificate.pem; ssl_certificate_key ssl/key.pem; root /var/www/html; # chaque fois qu'un client demande demo.html, envoyez également # /style.css, /image1.jpg et /image2.jpg location = /demo.html { http2_push /style.css; http2_push /image1.jpg; http2_push /image2.jpg; } }
Vous pouvez facilement vérifier que le push du serveur est en vigueur en utilisant l'une des deux méthodes suivantes :
nghttp
Voici comment utiliser les outils de développement de votre navigateur pour confirmer que le serveur push est activé, en prenant Google Chrome comme exemple. Sur la figure, la colonne Initiateur de l’onglet Réseau des outils de développement de Chrome montre que plusieurs ressources ont été envoyées au client lors d’une requête sur /demo.html.
nghttp
)En plus des outils de navigateur Web, vous pouvez utiliser le client de ligne de commande nghttp
du projet nghttp2.org pour vérifier que la transmission du serveur est effective. Vous pouvez télécharger le client de ligne de commande nghttp
depuis GitHub ou installer le package de système d’exploitation approprié lorsqu’il est disponible. Pour Ubuntu, utilisez le package nghttp2-client
.
Dans le résultat, l’astérisque (*) indique les ressources envoyées par le serveur.
$ nghttp -ans https://example.com/demo.html id responseEnd requestStart processus code taille requête chemin 13 +84.25ms +136us 84.11ms 200 492 /demo.html 2 +84.33ms * +84.09ms 246us 200 266 /style.css 4 +261.94ms * +84.12ms 177.83ms 200 40K /image2.jpg 6 +685.95ms * +84.12ms 601.82ms 200 173K /image1.jpg
Dans bien des cas, il est peu pratique, voire impossible, d’énumérer les ressources à pousser dans le fichier de configuration NGINX. C’est pourquoi NGINX prend aussi en charge la convention d’interception des en-têtes Link preload
, puis pousse les ressources indiquées dans ces en-têtes. Pour activer le préchargement, ajoutez la directive http2_push_preload
à la configuration :
server { # Assurez-vous que HTTP/2 est activé pour le serveur listen 443 ssl http2 ; ssl_certificate ssl/certificate.pem; ssl_certificate_key ssl/key.pem; root /var/www/html; # Intercepter l'en-tête du lien et lancer les push demandés location = /myapp { proxy_pass http://upstream; http2_push_preload on; } }
Par exemple, lorsque NGINX fonctionne comme un proxy (pour HTTP, FastCGI ou d’autres types de trafic), le serveur en amont peut ajouter un en-tête de lien
comme celui-ci à sa réponse :
Lien : </style.css> ; as=style ; rel=preload
NGINX intercepte cet en-tête et lance un push serveur de /style.css . Le chemin dans l'en-tête du lien
doit être absolu – les chemins relatifs comme ./style.css ne sont pas pris en charge. Le chemin peut éventuellement inclure une chaîne de requête.
Pour envoyer plusieurs objets, vous pouvez fournir plusieurs en-têtes de lien
ou, mieux encore, inclure tous les objets dans une liste séparée par des virgules :
Lien : </style.css>; as=style; rel=preload, </favicon.ico>; as=image; rel=preload
Si vous ne voulez pas que NGINX envoie automatiquement une ressource préchargée, ajoutez le paramètre nopush
à l'en-tête :
# La ressource n'est pas poussée Lien : </nginx.png>; as=image; rel=preload; nopush
Lorsque http2_push_preload
est activé, vous pouvez également lancer le push du serveur de préchargement en définissant l'en-tête de réponse dans votre configuration NGINX :
add_header Lien "</style.css>; as=style; rel=preload";
La spécification HTTP/2 ne traite pas la question de savoir quand lancer la poussée de ressources. Vous devez pousser des ressources aux clients uniquement si vous savez qu’ils en auront probablement besoin et qu’ils ne les ont pas déjà en cache.
Vous pouvez choisir de n'envoyer des ressources aux clients que lors de leur première visite sur le site. Par exemple, testez la présence d'un cookie de session et configurez l’en-tête Link
de façon conditionnelle pour ne précharger les ressources que si ce cookie est absent.
Si les clients se comportent correctement en ajoutant le cookie dans les requêtes suivantes, NGINX transmet les ressources aux clients une seule fois par session de navigation avec cette configuration :
server {
listen 443 ssl http2 default_server;
ssl_certificate ssl/certificate.pem;
ssl_certificate_key ssl/key.pem;
root /var/www/html;
http2_push_preload on;
location = /demo.html {
add_header Set-Cookie "session=1";
add_header Link $resources;
}
}
map $http_cookie $resources {
"~*session=1" "";
default "</style.css>; as=style; rel=preload, </image1.jpg>; as=image; rel=preload, </image2.jpg>; as=image; rel=preload";
}
Pour mesurer l'effet du push serveur, nous avons créé une page de test simple, /demo.html , qui fait référence à une feuille de style distincte, /style.css . La feuille de style fait également référence à deux images. Nous avons testé les temps de chargement des pages en utilisant trois configurations différentes :
GET
séquentiels (pas d'optimisation) – Le navigateur a chargé les ressources lorsqu'il a découvert qu'elles étaient nécessairesde lien
) ont été inclus dans la première réponse pour indiquer au navigateur de charger les dépendancesNous avons effectué plusieurs tests de chaque configuration en utilisant HTTP, HTTPS ou HTTP/2. Les deux premières configurations s'appliquent aux trois protocoles et le serveur envoie uniquement des données vers HTTP/2.
Le comportement a été mesuré à l’aide des outils de développement Chrome. Le comportement le plus courant de chaque configuration a été évalué et moyenné, et les temps ont été corrélés avec le RTT du lien (mesuré à l'aide de ping
) pour illustrer l'effet mécanique de chaque méthode.
GET
s'achève en environ 1 RTT.GET
de préchargement.keepalive_timeout
et http2_idle_timeout
ont été utilisées pour fermer rapidement les connexions keepalive.Nous avons délibérément choisi un test simple pour illustrer le fonctionnement des indices de préchargement et du serveur push. Le serveur push améliore la latence d'une RTT par rapport aux indices de préchargement dans des cas simples, et offre un gain encore plus important face aux requêtes GET
séquentielles non optimisées et à la découverte des ressources dépendantes.
Les cas d’usage plus réalistes comprennent de nombreuses variables supplémentaires : plusieurs ressources dépendantes, plusieurs sources, et même le risque de bandwith gaspillé en envoyant des ressources déjà en cache ou non immédiatement nécessaires. Les différences entre navigateurs impactent aussi les performances. Vos résultats différeront sûrement de ce test simple.
Par exemple, l'équipe Chrome a publié des recommandations détaillées sur le moment de déployer le push serveur et a effectué des mesures sur des sites plus complexes pour comparer les effets de l'absence d'optimisation, des conseils de préchargement et du push serveur sur HTTP/2. Leur rapport Rules of Thumb for HTTP/2 Push mérite d'être lu par quiconque envisage de déployer le serveur HTTP/2 Push en production.
Si vous pouvez déterminer à l'avance quelles ressources sont nécessaires, vous tirez un réel avantage à ce que les serveurs en amont envoient un indice de préchargement. L’envoi supplémentaire de ces ressources offre un bénéfice modeste mais mesurable, et peut parfois gaspiller de la bande passante ou retarder des ressources essentielles. Testez et surveillez avec soin toute configuration de poussée serveur.
Les informations ci-dessous sont basées en partie sur les recherches effectuées dans l'article de blog très détaillé de Jake Archibald intitulé HTTP/2 push is tougher than I thought .
Le serveur HTTP/2 pousse généralement en avance les ressources dont dépend une requête lorsque vous demandez un contenu. Par exemple, quand vous demandez une page web, le serveur vous envoie aussi les feuilles de style, polices et images associées.
Lorsqu’un client établit une connexion HTTP/2, le serveur peut choisir d’envoyer une ou plusieurs réponses push serveur sur cette connexion. Ces push délivrent des ressources que vous n’avez pas demandées explicitement.
Le client peut soit rejeter un push (en envoyant une trame RST_STREAM
) soit l'accepter. Le client stocke le contenu poussé dans un « cache push » local associé à la connexion HTTP/2.
Plus tard, quand le client demande une ressource via une connexion HTTP/2 déjà établie, il consulte le cache push de la connexion pour trouver une réponse terminée ou en cours. Il privilégie la ressource en cache plutôt que d’envoyer une nouvelle requête HTTP/2.
Une ressource poussée reste dans le cache push par connexion jusqu’à ce que vous l’utilisiez ou que la connexion HTTP/2 se ferme :
Cela a plusieurs implications :
Vous pouvez consulter une liste beaucoup plus détaillée des problèmes dans l'article de blog de Jake Archibald, HTTP/2 push is tougher than I thought .
Le push du serveur HTTP/2 est une fonctionnalité intéressante. Assurez-vous de tester minutieusement la configuration push de votre serveur HTTP/2 et soyez prêt à recourir aux indications de préchargement dans les cas où cela donne un comportement plus prévisible et plus sensible au cache.
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."