[英]Nodejs http2 behind (nginx or otherwise Webserver) with Push in Nodejs
我正在嘗試更新我們的在線商店以使用具有服務器推送功能的HTTP / 2,但我找不到像Nginx這樣的網絡服務器(用於代理和其他一些東西)與上游HTTP / 2的解決方案。 我們目前正在將Node.js與節點HTTP模塊一起使用,但是想切換到節點spdy模塊。 spdy模塊支持帶服務器推送的HTTP / 2。 我已經嘗試過H2O作為Nginx的替代品,但它也不支持HTTP / 2上游。
我現在有點失落,需要幫助。
Nginx 剛剛添加了對HTTP / 2 Push的支持,所以除非你正在摩擦最新的主線版本,否則你將無法做到這一點。 還因為它是如此新穎,它仍然存在一些問題 。 Nginx不支持后端連接上的http2(並聲明他們不支持這個 )。 所以你不能像你建議的那樣直接從下游系統推出。
無論如何,這是否是推動的最佳方式還存在一些問題。 即使客戶端不支持推送,下游系統也可以推送到上游代理服務器 - 這是浪費的推送。
因此,更好的方法是從代理推送並讓下游系統告訴上游系統(通過鏈接頭)執行該推送。 這在降低復雜性方面有幾個優點,允許下游系統推送它可能無法控制的資產(例如靜態資產,如樣式表,JavaScript,圖像......等),已推送資產的中央存儲(緩存摘要),也不要求HTTP / 2一直受到支持(鏈接頭可以像HTTP / 2一樣通過HTTP / 1.1發送)。
通過鏈接頭從上游代理推送的主要缺點是,您必須等待所請求的資源准備就緒,因為從響應中讀取了鏈接頭。 如果請求資源需要一些時間來生成,那么在處理其他資源時開始推送可能更有利。 這是通過新的103 Early Hints HTTP狀態代碼解決的 ,您可以在稍后發送主200狀態代碼之前回復。 此早期消息可以具有鏈接頭,其可以由上游代理讀取並用於推送資源。 我不確定Nginx的實現是否會支持這一點。
順便說一下,Apache已經支持Push一段時間了,並且有一個更加成熟的實現。 它通過直接Apache配置或鏈接頭支持它(包括通過103響應,默認情況下配置為在兼容性問題時不發送)。 它甚至支持通過HTTP / 2代理后端,但由於上述原因,不支持直接推送后端連接 。 其他一些不太知名的服務器(例如H2O )也比Nginx更好地支持HTTP / 2。
最后,如果使用CDN,那么他們可能支持HTTP / 2推送(通常通過鏈接頭),而無需升級任何后端基礎設施。 事實上,Cloudflare是一個基於Nginx的CDN,它有一段時間的HTTP / 2推送,事實上它是兩個Cloudflare工程師,他們已經將他們的實現移植到基本的Nginx代碼 。
在NGINX 1.13.9(今天剛推到主線)之后,您可以通過使用ngx_http_v2_module
編譯來啟用HTTP / 2服務器。
如果您對最近添加的內容感興趣,那么這是添加了大部分功能的提交: hg.nginx.org:HTTP / 2:服務器推送 。
它的使用相對簡單:將http2_push_preload
指令添加到代理Node的服務器,然后從節點添加Link
頭(如W3規范中所述 - https://www.w3.org/TR/preload/# server-push-http-2 )然后NGINX將完成發送指示服務器推送的h2幀的工作。
例如,假設您有一個服務於常規index.html
的/
endpoint,但也將image.svg
推image.svg
客戶端。
在NGINX中,您可以配置上游服務器,然后在服務器配置中啟用服務器配置上的http2_push_preload
:
# Add an upstream server to proxy requests to.
upstream sample-http1 {
server localhost:8080;
}
server {
# Listen on port 8443 with http2 support on.
listen 8443 http2;
# Enable TLS such that we can have proper HTTP2
# support using browsers.
ssl on;
ssl_certificate certs/cert_example.com.pem;
ssl_certificate_key certs/key_example.com.pem;
# Enable support for using `Link` headers to indicate
# origin server push.
http2_push_preload on;
# Act as a reverse proxy for requests going to /proxy/*.
#
# Because we don't want to rewrite our endpoints in the
# Node app, rewrite the path such that `/proxy/lol` ends up
# as `/lol`.
location / {
proxy_pass http://sample-http1;
}
}
然后在應用程序的NodeJS,你會成為/
因為你通常做,但額外添加Link
標題的回應:
response.setHeader('Link', '</image.svg>; rel=preload; as=image');
ps:是的,你要保留那些尖括號; 我並不是說你應該更換它們。
順便說一下,我剛剛給出的示例(帶有一些調試技巧)在這里寫完: https : //ops.tips/blog/nginx-http2-server-push/ 。
您可以從源代碼編譯/重新編譯nginx,並包含--with-http_v2_module
配置參數以啟用HTTP2推送功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.