HTTP/2 中的 Server Push 討論
提醒:本文最後更新於 1304 天前,文中所描述的資訊可能已發生改變,請謹慎使用。
本文不討論 Server Push 是什麼,也不討論如何使用 Server Push。
如果服務端想要推送的資源本地已經快取過,客戶端會發送
RST_STREAM
告訴服務端不要再傳了。不過根據我的觀察,H2O 服務端在收到RST_STREAM
之前,已經發出了資源,造成了流量的浪費。具體原因,我正在向 H2O 作者求證。
Kazuho Oku 的回答:
Because the HEADERS frame has left the server before the RST_STREAM sent from the client reaches the server.
這是因為客戶端發出的 RST_STREAM 幀到達服務端之前,那些 HEADERS 幀(注:HTTP2_SESSION_RECV_HEADERS 和 HTTP2_SESSION_RECV_DATA)已經離開了服務端。
The issue is known to the protocol designers of HTTP/2, and my understanding is that there is a discussion on how the client should notify the server if it already has the asset cached. Until such mechanism gets introduced, we cannot fix the issue (or in other words you should better not use push if the negative impact of a cached content being pushed outweighs the positive impact of pushing the content every time).
HTTP/2 協議制定者已經知道這個問題的存在,我認為應該討論一下客戶端已經快取資源時,如何通知服務端。直到 HTTP/2 協議定義相應的機制前,我們無法修復這個問題(換句話說,如果快取過的資源每次都被 Push 這件事所帶來的弊端大於好處,你就不應該使用這個功能)。
Tatsuhiro Tsujikawa 的回答:
It is a race condition, between server starts sending pushed data, and it receives RST_STREAM.
服務端開始 Push 資料與收到 RST_STREAM 幀這二者是競爭狀態。
If server receives RST_STREAM while sending pushed data, it will stop sending remaining data.
如果服務端正在 Push 資料時收到了 RST_STREAM 幀,它會停止傳送剩餘資料。
People argue the wasted bandwidth when server push is involved. That is by design.
人們爭論啟用 Server Push 所帶來的頻寬浪費。但設計就是如此。
Server push is asynchronous, and just send server's discretion, without client's confirmation, to eliminate latency penalty. There will be novel use cases for server push, but here we discuss the use case for ordinal web pages. In this case, server push is introduced to eliminate ugly inlining we used to avoid additional HTTP request because in HTTP/1.1 request is expensive.
Server Push 是非同步的,會發送服務端認為需要傳送的內容,不需要客戶端確認,目的是消除網路延遲。今後肯定會有關於 Server Push 的新穎用法出現,但這裡我們要討論在現有網頁中使用 Server Push。這時候,Server Push 的作用是取代「由於 HTTP/1.1 的連線數很寶貴,為避免產生額外 HTTP 請求而引入的」資源內聯——它太醜陋了。
We mean inlining here is data URI of images in html page, or CSS, to reduce the number of requests.
我們這裡說的內聯,是指將圖片通過 Data URI 的方式內建在 HTML 或者 CSS 裡,作用是減少請求數。
In HTTP/2, requests are cheap now, and we don't have to do inlining. But without inlining there could be latency while browser discovers link and requests to the server. Server push is useful in this situation. You can push contents we used to inlined in html. Now we are no worse than HTTP/1.1 inlining, even if we "waste" bandwidth. In HTTP/1.1, these assets are always inlined, so they are always wasted. Also data URI is horrible, just inflating bytes. Now in server push, we have separate cache space, and if client only wants to download html, without formally inlined assets, it can do so by disabling push. And we allow client to cancel this push, although it may too late in some situation.
在 HTTP/2 裡,請求變得非常廉價,我們不再需要內聯了。但是如果沒有內聯,瀏覽器在發現外鏈資源併發送請求之前,會有一段時間的延遲。這時候 Server Push 就變得非常有用了。之前需要內聯在 HTML 裡的資源現在可以改由服務端 Push。現在即使「浪費」了頻寬,也不比 HTTP/1 的內聯差。因為在 HTTP/1.1 裡,那些資源總是會被內聯,總會被浪費。另外,Data URI 非常可怕,因為編碼後位元組數會變多。現在有了 Server Push,每個資源都有自己單獨的快取,如果客戶端只想下載沒有內聯資源的 HTML,可以通過禁用 Push 來實現。我們也允許客戶端取消 Push,儘管有時候已經太遲了。
But still we just improving situation, not worsening it.
但是這一切仍然是讓情況變得更好,而不是更糟糕。
Ilya Grigorik 的回答:
+1 to everything @tatsuhiro-t said.
+1 完全同意樓上所說。
Also, note that the client can limit the server in what it's allow to send: (a) the client can limit max number of push streams, and (b) it can set a low flow control window to limit how much data the server is allowed to send in first RTT. Between these two the client has all the controls to govern how and where push is used -- e.g. if you're in data savings mode, you may want to tweak either or both of those. Beyond that, the server can also be smarter about when it pushes resources -- e.g. if it pushes a cacheable resource on first session hit, and then receives a second session hit on same connection (which is within cache lifetime of first push), then it can omit pushing that resources.. and so forth.
同時,請注意客戶端可以限制服務端能 Push 什麼:1)客戶端可以限制 Push 流的最大數目;2)客戶端可以設定一個很低的流量控制視窗,來限制服務端在第一個往返內傳送的資料大小。基於這兩點,客戶端可以完全控制 Push 怎麼用和用在哪——例如,如果你在使用省流模式,你可能會調整前面兩個策略之一或者全部。除此之外,服務端在 Push 資源時可以更聰明一些——例如,如果服務端在第一個 Session 裡 Push 了一個可被快取的資源,然後又在同一個連線上收到第二個 Session(在第一次 Push 資源的快取生命週期內),這時候就可以不再 Push 這個資源了。。諸如此類。
我的理解:
頁面有一些很重要的資源需要儘快載入,例如核心的 css 檔案。瀏覽器載入它們的延遲來自多方面,這幾個是 HTTP/2 能解決的:1)同域名併發連線數限制造成的阻塞時間;3)瀏覽器從 HTML 中找出外鏈資源這段時間;3)瀏覽器發起請求到服務端收到請求這段時間。
HTTP/2 的多路複用特性消除了同域名併發連線數限制;Server Push 則會在客戶端請求頁面 HTML 時,新建流將最重要的資源一併返回。同時,如果服務端要推送的資源瀏覽器已經快取過,客戶端會發送 RST_STREAM
幀來終止流,服務端收到這個訊號之前所傳輸的資料就造成了頻寬浪費。這個問題可以通過在服務端記錄給每個客戶端傳送過何種資源,何時過期來優化。實際上,大多數時候頻寬都不是瓶頸,延遲才是首先需要考慮的。
另外,W3C 的 Preload 文件中,定義了一種通過響應頭部儘早告訴瀏覽器需要載入哪些資源的方案。這個方案非常輕量,幾乎沒有副作用,也推薦使用。
--EOF--
發表於 2015-06-16 21:06:17 ,並被新增「 HTTP2 」標籤 。檢視本文 Markdown 版本 »
提醒:本文最後更新於 1304 天前,文中所描述的資訊可能已發生改變,請謹慎使用。
相關推薦
HTTP/2 中的 Server Push 討論
提醒:本文最後更新於 1304 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 本文不討論 Server Push 是什麼,也不討論如何使用 Server Push。 如果服務端想要推送的資源本地已經快取過,客戶端會發送 RST_STREAM 告訴服務端不要再傳了。不過根據我的觀察,H2O
HTTP/2 服務器推送(Server Push)教程(HTTP/2 協議的主要目的是提高網頁性能,配置Nginx和Apache)
tcp tac 面板 參考 寫入 修改 現實 多個 後端 HTTP/2 協議的主要目的是提高網頁性能。 頭信息(header)原來是直接傳輸文本,現在是壓縮後傳輸。原來是同一個 TCP 連接裏面,上一個回應(response)發送完了,服務器才能發送下一個,現在可以多個回
HTTP/2 Server Push
The new version of the HTTP protocol, HTTP/2 lets the server to push content to the client before the client requests the particular content. There are
HTTP/2 伺服器推送(Server Push)教程
HTTP/2 協議的主要目的是提高網頁效能。頭資訊(header)原來是直接傳輸文字,現在是壓縮後傳輸。原來是同一個 TCP 連線裡面,上一個迴應(response)傳送完了,伺服器才能傳送下一個,現在可以多個迴應一起傳送。伺服器推送(server push)是 HTTP/2
Centos 6.9中 http-2.2 中的一些基本操作和 https 的實現
http http-2.2 https 首先聲明: 接下來的所有的操作都是基於防火墻和selinux關閉的情況下;是基於本地的實現;1.建立httpd服務,要求: 1) 提供兩個基於名稱的虛擬主機www1, www2;要求每個虛擬主機都有單獨的錯誤日誌
Centos 7.4 中http-2.4 的基本實現和 https 的實現
http-2.4 https 1.建立httpd服務,要求: 1) 提供兩個基於名稱的虛擬主機www1, www2;要求每個虛擬主機都有單獨的錯誤日誌和訪問日誌; 2) 通過www1的/server-status提供狀態信
H2O 中的 Cache-Aware Server Push 簡介
提醒:本文最後更新於 1127 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 Server Push 會在客戶端請求頁面 HTML 時,新建一個流將最重要的資源一併返回。同時,如果服務端要推送的資源瀏覽器已經快取過,客戶端會發送 RST_STREAM 幀來終止流,服務端收到這個訊號之前所傳
如何讓nginx修改Response HTTP Header中的server的值
伺服器的作業系統版本、提供HTTP服務的軟體版本等資訊屬於伺服器安全資訊,防止它們的資訊洩露有助於防止黑客定向尋找特定作業系統或軟體版本存在的漏洞,伺服器也就多一重保障。nginx在每個Response中寫入了Server這個Header,Server的值明確標
Git 2.x 中git push時遇到 push.default 警告的解決方法
近在學習使用 git&GitHub,然後今天遇到了一個問題。在執行 git add 和 git commit 操作之後,再進行 git push 操作,出現瞭如下提示: $ git push warning: push.default is unset; its implicit
SpringMVC常用註解2獲取http請求中的cookie,header和ServletAPI
[email protected]註解獲取cookie中的值 @RequestMapping("/ShowCookie") public String showCookieV
OkHttp3中的HTTP/2首部壓縮
當前網路環境中,同一個頁面發出幾十個HTTP請求已經是司空見慣的事情了。在HTTP/1.1中,請求之間完全相互獨立,使得請求中冗餘的首部欄位不必要地浪費了大量的網路頻寬,並增加了網路延時。以對某站點的一次頁面訪問為例,直觀地看一下這種狀況: Header 1 Header 2 如
如何在 Apache 中啟用 HTTP/2
剛釋出的 Apache httpd 2.4.17 終於支援 HTTP/2 了。這個頁面給出了一些如何構建/部署/配置的建議。目的是為了大家發現 bugs 時能升級它,或者給一些能更好工作的建議。 最後,這會歸併回到官方 Apache 文件,這裡只會留下一個到
在centos中搭建基於smart http的git server
# 由於公司的特殊需求,需要將git整合到IBM的RTC裡面,而RTC使用的是http,所以要只能放棄了git原生的ssh,轉而使用smart http,git server搭建在centos系統上。博主在瀏覽了N多教程發現都是比較殘缺的,並沒有針對smart
HTTP協議(2)HTTP協議中的請求資訊
1:請求行 請求行分為三部分: 請求方式:GET、POST 資源路徑:/servlet/request http協議版本:http/1.1HTTP/0.9 :只接受GET一種請求方法,沒有在通訊中指定版本號,且不支援請求頭。由於該版本不支援POST方法,因此客戶端無法向
移除http響應中的多餘的頭(X-AspNet-Version,Server等)
網上搜索出很多方法了,這裡記錄一下: 如果是asp.net mvc的話還得在global.ascx中加入: 至於移除Server頭,按網上的寫法寫httpmoudle後發現無效的,最後還是用了微軟官方的UrlScan工具,搜尋下載安裝後在 C:WindowsSystem32
Oracle12.2中新增的分區功能
功能 防止 新功能 時間 如果 針對 alt 關鍵字 只讀 Oracle 12.2已經發布一段時間,公網上也可以下載試用。針對12.2,partitioning(分區)也有了不少增強。自動列表分區多字段列表分區只讀分區分區維護時允許過濾在線轉換非分區表為分區表帶分區的外部
Unity3D 遊戲引擎之C#使用Socket與HTTP連接server數據傳輸包
tco 類型 oba connect asp bre amp 客戶 star 近期比較忙。有段時間沒寫博客拉。近期項目中須要使用HTTP與Socket。雨松MOMO把自己這段時間學習的資料整理一下。有關Socket與HTTP的基礎知識MOMO就不贅述拉,不懂得朋友自己
ASP.NET Core HTTP 管道中的那些事兒
那些事兒 管道 IApplicationBuilderIApplicationBuilder 是應用大家最熟悉它的地方應該就是位於 Startup.cs 文件中的 Configure 方法了吧public void Configure(IApplicationBuilder app, ILoggerF
windows下使用Wireshark調試chrome瀏覽器的HTTP/2流量
ogl tps bug files 環境變量設置 erp res -m brush 1.在Wireshark官網(https://www.wireshark.org/#download)下載對應的Wireshark安裝包,進行安裝 2.增加系統環境變量設置(計算機 -- 右
斐迅面試記錄—Http協議中的Header
art apple -c etag cookie md5 頭信息 一點 zip HTTP Request的Header信息 1、HTTP請求方式 如下表: 說明: 主要使用到“GET”和“POST”。 實例: POST /test/tupian/cm HTTP/1.1