天天看點

阿裡雲 CDN HTTPS 最佳實踐系列——HTTP/2

HTTP/2 是最新的 HTTP 協定,已于2015年5月份正式釋出,Chrome、 IE11、Safari 以及 Firefox 等主流浏覽器已經支援 HTTP/2 協定。阿裡雲 CDN 在2016年7月份開始全網支援 HTTP/2,是國内第一家全網支援 HTTP/2 的 CDN 提供商。

HTTP/2 是新技術,一些底層代碼庫在實作時可能不完善,在一些特殊場景下可能就出問題,我們遇到過一些 android 庫實作有問題,導緻開啟 HTTP/2 就經常通路失敗,關閉 HTTP/2 就完全正常。是以對于一些 HTTP/2 有問題的域名需要關閉 HTTP/2,一些沒有問題的域名不能關閉 HTTP/2。但是 Tengine(nginx)的 http2 開關參數是 ip:port 級别,不是 server 級别,也就是說如果多個域名同時使用同一個 IP,無法針對 server 來打開或者關閉。

阿裡雲 CDN HTTPS 最佳實踐系列——HTTP/2

上面的配置中,www.a.com 和 www.b.com 使用了同一個 IP 端口, www.a.com 打開了 http2,www.b.com 沒有打開 http2,但是 www.b.com 的 http2 同樣也被打開了,無法關閉。

我們知道,任何公司的 IP 資源都是稀缺的,很多域名都是共用一個 IP 或者 共用幾個 IP,不可能為需要關閉 HTTP/2 的域名配置設定一個 IP 資源,是以最核心的需求就是針對域名級别來配置 HTTP/2 開啟或者關閉。

先來看一看 Tengine 中 ip:port 和 server 的關系:

阿裡雲 CDN HTTPS 最佳實踐系列——HTTP/2

多個 server 塊可能會 listen 同一個 ip:port,一個 server 也可能 listen 多個 ip:port,是以 ip:port 和 server 是多對多的關系,但在 Tengine 配置塊中并沒有 listen 塊,是以從配置檔案中直覺看 server 塊包含了 listen,似乎 server 塊比 listen 更底層,進而造成了在一個 server 塊 listen 指令參數中配置了 http2 不會影響其他 server 的 http2 的假象,但其實 ip:port 更底層。

如上圖所示,在 Tengine 配置解析階段會把所有 server 塊中配置的 listen ip:port 添加到一個 listening servers 表(數組)中,當 http 請求上來之後,先從這個表中查到 addr_conf 資訊,在配置中 listen 指令的 flag 參數(比如: ssl、http2)都會放到這個結構中,并沒有放到 server 中,是以就會導緻這個 ip:port 的 listen 參數對所有關聯的 server 生效。

知道了 Tengine 底層實作原理,修複起來也很容易了。我們也對 HTTP/2 開關實作了動态配置,進而HTTP/2 的開關便可以通過 CDN 控制台根據域名來設定了。如圖:

阿裡雲 CDN HTTPS 最佳實踐系列——HTTP/2

需要開啟或者關閉 HTTP/2 的域名隻需要在 CDN 控制台上修改一下就可以立馬生效了。

下一篇我們将介紹CDN HTTPS 動态密鑰套件,敬請關注!