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, défini dans la spécification HTTP/2 , permet à un serveur de pousser de manière préventive des ressources vers un client distant, en anticipant que le client pourrait bientôt demander ces ressources. Ce faisant, vous pouvez potentiellement réduire le nombre de RTT (temps d’aller-retour – le temps nécessaire pour une demande et une réponse) dans une opération de chargement de page d’un RTT ou plus, offrant ainsi une réponse plus rapide à l’utilisateur.
Le serveur push peut être utilisé pour préparer un client avec des feuilles de style, des images et d'autres ressources dont il aura besoin pour restituer une page Web. Vous devez veiller à n’envoyer que les ressources nécessaires ; n’envoyez pas des ressources qu’un client est susceptible d’avoir déjà mises 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
comme suit :
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 Web pour vérifier que la fonction Push du serveur est en vigueur, en utilisant Google Chrome comme exemple. Dans la figure, la colonne Initiateur de l'onglet Réseau des outils de développement de Chrome indique que plusieurs ressources ont été transmises au client dans le cadre d'une demande pour /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 la sortie, l'astérisque (*) marque les ressources qui ont été poussé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 de nombreuses situations, il est peu pratique, voire impossible, de répertorier les ressources que vous souhaitez pousser dans le fichier de configuration NGINX. Pour cette raison, NGINX prend également en charge la convention d'interception des en-têtes de préchargement de lien
, puis de transmission des ressources identifiées dans ces en-têtes. Pour activer le préchargement, incluez la directive http2_push_preload
dans 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 souhaitez pas que NGINX envoie une ressource préchargée, ajoutez le paramètre nopush
à l'en-tête :
# La ressource n'est pas pousséeLien : </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 n’aborde pas le défi consistant à déterminer s’il faut ou non pousser les ressources. De toute évidence, il est préférable de ne transmettre des ressources aux clients que si vous savez à la fois qu’ils sont susceptibles d’en avoir besoin et qu’il est peu probable qu’ils l’aient déjà mise en cache.
Une approche possible consiste à proposer des ressources aux clients uniquement lors de leur première visite sur le site. Vous pouvez tester la présence d'un cookie de session, par exemple, et définir l'en-tête Link
de manière conditionnelle, de sorte que les ressources ne soient préchargées que si le cookie de session n'est pas présent.
En supposant que les clients se comportent bien et incluent le cookie dans les requêtes ultérieures, avec la configuration suivante, NGINX transmet les ressources aux clients une seule fois par session de navigateur :
serveur {
écoute 443 ssl http2 default_server;
certificat_ssl ssl/certificate.pem;
clé_certificate_ssl ssl/key.pem;
racine /var/www/html;
http2_push_preload activé;
emplacement = /demo.html {
add_header Set-Cookie "session=1";
add_header Lien $ressources;
}
}
map $http_cookie $ressources {
"~*session=1" "";
par défaut "</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'exécute en environ 1 RTT.GET
de préchargement.keepalive_timeout
et http2_idle_timeout
ont été utilisées pour fermer rapidement les connexions keepalive.Ce test a été volontairement simple, afin de mettre en évidence les mécanismes des indices de préchargement et du push serveur. Le push serveur offre une amélioration de 1-RTT par rapport aux indications de préchargement dans des situations simples, et une amélioration plus importante par rapport aux requêtes GET
séquentielles non optimisées et à la découverte de ressources dépendantes.
Les cas d’utilisation plus réalistes comportent beaucoup plus de variables : plusieurs ressources dépendantes, plusieurs sources, voire la possibilité d’un gaspillage de bande passante en poussant des ressources déjà mises en cache ou qui ne sont pas immédiatement nécessaires. Les incohérences du navigateur affectent également les performances. Votre kilométrage variera certainement par rapport à ce simple test.
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.
La conclusion pragmatique est que si vous pouvez identifier à l’avance les ressources nécessaires, il y a un réel avantage à ce que les serveurs en amont envoient une indication de préchargement. L’avantage supplémentaire de pousser ces ressources est faible mais mesurable, mais peut éventuellement entraîner un gaspillage de bande passante et des retards pour les ressources nécessaires. Vous devez tester et surveiller attentivement toutes les configurations de serveur push.
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 push du serveur HTTP/2 est généralement utilisé pour envoyer des ressources dépendantes de manière préventive lorsque le client demande une ressource. Par exemple, si un client demande une page Web, le serveur peut envoyer des feuilles de style, des polices et des images dépendantes au client.
Lorsqu'un client établit une connexion HTTP/2, le serveur peut choisir de lancer une ou plusieurs réponses push du serveur via la connexion. Ces push envoient des ressources que le client n'a pas explicitement demandées.
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, lorsque le client effectue une demande de ressource à l’aide d’une connexion HTTP/2 établie, il vérifie le cache push de la connexion pour obtenir une réponse terminée ou en transit à la demande. Il utilise la ressource mise en cache plutôt que de faire une nouvelle requête HTTP/2 pour la ressource.
Toute ressource poussée reste dans le cache push par connexion jusqu'à ce que (a) elle soit utilisée ou (b) la connexion HTTP/2 soit fermée :
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."