再見 HTTP 1-1,怎樣把網站升級成 HTTP 2?
最近想給網站的協議升級 HTTP2,之前都是 HTTP 1.1。
由於網站並行加載的資源比較多,HTTP 2 相比 HTTP 1.1 來說,所有的連接共享一個 TCP 連接,同時一個域名下還沒有最多同時連接數的限制,加載速度會比 1.1 好一些。
關於 HTTP2 的另外一些好處,大家可以這篇文章:https://blog.fundebug.com/2019/03/07/understand-http2-and-http3/,講得很透徹,順帶還講了講 HTTP 3 也就是 QUIC 的相關知識。
正題
廢話不多說了進入正題,我現在要把我的某個網站升級成 HTTP2,而且我的所有網站都是基於 Kubernetes 來 serve 的,域名解析都是通過 Nginx Ingress 來做的,那我怎麼專門給某個網站升級 HTTP2 呢?
最重要的配置就在這裏了:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/,我們通過修改 Ingress Controller 就可以控制 HTTP 2 的開關。
那這個 ConfigMap 又和 Ingress 什麼關係呢?
答案如下:
-
Ingress 可以配置哪個域名轉發到哪個後端來處理。
-
Ingress 的使用需要依賴一個 Ingress Controller。
-
每個 Ingress Controller 會對應一個 ConfigMap 來配置當前 Nginx 服務器的行爲。
在配置之前,所有的網站都是使用同一個 Ingress Controller 來處理的,而且 Ingress Controller 對應的 ConfigMap 都是一樣的。
所以爲了單獨讓某個網站應用 HTTP 2,而不影響其他網站,那就需要使用單獨的 ConfigMap 來處理,那就需要一個新的 Ingress Controller。
所以,HTTP 1.1 和 HTTP 2 都分別對應一套 Ingress Controller 和 ConfigMap 的配置。
這樣思路就清晰了。
所以,接下來我需要新建一個 Ingress Controller,這裏我的所有網站所在的 namespace 是 scrape,所以直接用 helm 在 scrape 這個 namespace 下新建一個 Nginx Ingress 套件,這裏就直接取名爲 ingress-nginx3 (因爲其他 namespace 已經有 ingress-nginx2 了,就順着取名)了:
helm install ingress-nginx3 -n scrape ingress-nginx/ingress-nginx
具體可以參見:https://kubernetes.github.io/ingress-nginx/deploy/
OK,好了之後,可以觀察到有一個對應的 ConfigMap 就生成了:
OK,這裏 yaml 文件類似如下:
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: ingress-nginx3
meta.helm.sh/release-namespace: scrape
creationTimestamp: "2021-05-16T13:24:53Z"
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx3
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/version: 0.46.0
helm.sh/chart: ingress-nginx-3.30.0
managedFields:
- apiVersion: v1
manager: Go-http-client
operation: Update
time: "2021-05-16T13:24:53Z"
- apiVersion: v1
manager: tke-apiserver
operation: Update
time: "2021-05-16T13:46:33Z"
name: ingress-nginx3-controller
namespace: scrape
resourceVersion: "2694665147"
selfLink: /api/v1/namespaces/scrape/configmaps/ingress-nginx3-controller
uid: bd60849d-be4c-4efa-9196-b00e8a4e2f8b
這裏我們需要單獨增加 HTTP2 的配置:
apiVersion: v1
+ data:
+ use-http2: "true"
kind: ConfigMap
metadata:
...
另外還有很多 ConfigMap 的配置,可以查閱官方文檔:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
這裏我就直接配置 use-http2
爲 true
了。
“
這裏有個很詭異的問題,我看文檔說 use-http2 默認就是 true,但不知道爲什麼之前一直不生效,我加了這個才生效。
”
OK,保存 yaml 即可,這樣配置工作就完成了大半了。
接下來,我們再把域名解析的地址修改成新建的 Nginx Ingress 套件中的 Ingress Controller 上就好了,Ingress Controller 背後會自動創建一個 Load Balance,對應一個公網 IP,改下域名解析地址即可。
我升級的是 spa16.scrape.center,所以只解析 spa16 的 A 地址即可。
改完之後,稍等片刻,ping 下驗證下就好了。
結果
最後升級成 HTTP 2 的示例網站如下:https://spa16.scrape.center/,加載時 Network 面板如下:
可以看到加載時 Protocol 就是 h2 了,意思就是 HTTP2。
而另一個沒升級的網站,網址如:https://spa15.scrape.center/,加載時 Network 面板如下:
這裏的 Protocol 還是 http/1.1,意思就是 HTTP 1.1。
通過 Waterfall 大家也能看出二者的差別吧,由於 HTTP 1.1 在 Chrome 瀏覽器中同時只有 6-8 個連接,所以可以看到後面 2 個 chunk 文件的加載被滯後了,而 HTTP2 就不會有這個問題,Waterfall 是不是很整齊?這就是 HTTP 2 的優勢之一。
OK,其實也是爬蟲示例網站的其中之一,大家可以來試試爬一爬啦~
後記
有的朋友可能問,就只改 Ingress 配置就好了嗎?Docker 鏡像裏面本身用了 HTTP 1.1 也行嗎?
是的!經過我的驗證,只有最後一層 Ingress 的配置改成 HTTP 2 就好了,Ingress 背後的 Docker 服務該啥樣就還是啥樣,也不用改鏡像,也不用改 Nginx 配置,也不用專門改 HTTPS,最後一層做了 HTTP 2 的支持就好了。
舒服!
作者:崔慶才
排版:崔慶才
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/aMK3EmaC7EabmMzAaditTg