Http2介紹

爲什麼要使用HTTP2

原因就是慢

 影響一個網絡請求的因素主要有兩個,帶寬和延遲。今天的網絡基礎建設已經使得帶寬得到極大的提升,大部分時候都是延遲在影響。

 **爲什麼延遲??**
  • 瀏覽器阻塞(HOL blocking):瀏覽器會因爲一些原因阻塞請求。瀏覽器對於同一個域名,同時只能有 4 
    個連接(這個根據瀏覽器內核不同可能會有所差異),超過瀏覽器最大連接數限制,後續請求就會被阻塞。
  • DNS 查詢(DNS Lookup):瀏覽器需要知道目標服務器的 IP 才能建立連接。將域名解析爲 IP的這個系統就是 DNS。這個通常可以利用DNS緩存結果來達到減少這個時間的目的。
  • 建立連接(Initial connection):HTTP 是基於 TCP 協議的,瀏覽器最快也要在第三次握手時才能捎帶 HTTP 請求報文,達到真正的建立連接,但是這些連接無法複用會導致每次請求都經歷三次握手和慢啓動。三次握手在高延遲的場景下影響較明顯,慢啓動則對文件類大請求影響較大。
  • 連接無法複用。每回請求個資源就會有一個請求連接跟斷開連接操作,大量請求不斷的請求連接跟斷開連接時間開銷大。

如何高響應速度?pipelining的出現

HTTP1.0 -> HTTP1.1 
前文介紹,HTTP 連接無法複用會導致每次請求都經歷三次握手和慢啓動。由圖可知pipelining可有效減少握手時間。

不過pipelining並不是救世主,它也存在不少缺陷:

  1. pipelining只能適用於http1.1,一般來說,支持http1.1的server都要求支持pipelining
  2. 只有冪等的請求(GET,HEAD)能使用pipelining,非冪等請求比如POST不能使用,因爲請求之間可能會存在先後依賴關係。
  3. head of line blocking並沒有完全得到解決,server的response還是要求依次返回,遵循FIFO(first in first out)原則。也就是說如果請求1的response沒有回來,2,3,4,5的response也不會被送回來。
  4. 絕大部分的http代理服務器不支持pipelining。
  5. 和不支持pipelining的老服務器協商有問題。
  6. 可能會導致新的Front of queue blocking問題。

普通的 HTTPS 網站瀏覽會比 HTTP 網站稍微慢一些,因爲需要處理加密任務。

HTTP2 VS HTTP1.1

  1. 多路複用。 
    多路複用通過多個請求stream共享一個tcp連接的方式(即所有的HTTP2.0的請求都在一個TCP鏈接上),解決了http1.x holb(head of line blocking)的問題,降低了延遲同時提高了帶寬的利用率。 
    此處輸入圖片的描述
  2. 壓縮頭部。 
    HTTP/2.0規定了在客戶端和服務器端會使用並且維護「首部表」來跟蹤和存儲之前發送的鍵值對,對於相同的頭部,不必再通過請求發送,只需發送一次。 
    如果首部發生變化了,那麼只需要發送變化了數據在Headers幀裏面,新增或修改的首部幀會被追加到“首部表”。首部表在 HTTP2.0的連接存續期內始終存在,由客戶端和服務器共同漸進地更新。 
    由於減少了大量請求頭數據的傳輸,緩解了網絡壓力,也提高了響應速度。 
    此處輸入圖片的描述
  3. 二進制分幀 
    在應用層與傳輸層之間增加一個二進制分幀層,以此達到“在不改動HTTP的語義,HTTP 方法、狀態碼、URI及首部字段的情況下,突破HTTP1.1的性能限制,改進傳輸性能,實現低延遲和高吞吐量。” 
    在二進制分幀層上,HTTP2.0會將所有傳輸的信息分割爲更小的消息和幀,並對它們採用二進制格式的編碼,其中HTTP1.x的首部信息會被封裝到Headers幀,而我們的request body則封裝到Data幀裏面。 
    此處輸入圖片的描述
  4. 並行雙向字節流的請求和響應 
    在HTTP2.0上,客戶端和服務器可以把HTTP消息分解爲互不依賴的幀,然後亂序發送,最後再在另一端把它們重新組合起來。注意,同一鏈接上有多個不同方向的數據流在傳輸。客戶端可以一邊亂序發送stream,也可以一邊接收服務器的響應,而服務器那端同理。 
    此處輸入圖片的描述
  5. 請求優先級 
    多路複用導致所有資源都是並行發送,那麼就需要「優先級」的概念了,這樣就可以對重要的文件進行先傳輸,加速頁面的渲染。
  6. 服務器推送 
    服務器推送是指在客戶端請求之前發送數據的機制。(根據請求資源猜測你可能還需要某某資源,提前推送資源緩存提高響應效率)

nginx升級HTTP2

1、升級準備

  1. 1、安裝編譯器
  2. yum -y install gc gcc gcc-c++ pcre* perl*
  3. 2、下載安裝包
  4. cd /usr/local
  5. wget http://nginx.org/download/nginx-1.12.2.tar.gz
  6. wget https://www.openssl.org/source/openssl-1.0.2e.tar.gz
  7. wget http://zlib.net/zlib-1.2.11.tar.gz
  8. 3、解壓安裝包
  9. tar -zxvf nginx-1.12.2.tar.gz
  10. tar -zxvf openssl-1.0.2e.tar.gz
  11. tar -zxvf zlib-1.2.11.tar.gz

2、安裝zlib

*1、cd zlib 2、./configure 3、make 4、make install

3、安裝openssl

1、cd openssl

2、安裝

./config shared zlib
make
make install
cd /usr/local/ssl/
./bin/openssl version -a

3、替換舊版OpenSSL

mv /usr/bin/openssl /usr/bin/openssl.old
mv /usr/include/openssl /usr/include/openssl.old
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl/ /usr/include/openssl

4、配置庫文件搜索路徑

echo "/usr/local/ssl/lib" >> /etc/ld.so.conf
ldconfig

5、測試新版本的OpenSSL是否正常工作

openssl version -a

4、安裝nginx

1、查看ngixn版本及其編譯參數,複製你已經編譯安裝好的模塊。

nginx -V

2、進入nginx源碼目錄

cd nginx
執行(在原有的參數上加上--with-zlib=/usr/local/zlib-1.2.11    --with-openssl=/usr/local/openssl-1.0.2e重編譯,如下例:)
./configure  --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module   --with-zlib=/usr/local/zlib-1.2.11 --with-openssl=/usr/local/openssl-1.0.2e  --with-pcre

3、然後

make   //千萬別make install,否則就覆蓋安裝了
make完之後在objs目錄下就多了個nginx,這個就是新版本的程序了

4、驗證新nginx是否可用驗證編譯後的nginx是否可以使用已有的配置

  1. ./objs/nginx -t

5、備份舊的nginx:

  1. cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

6、把新的nginx程序覆蓋舊的:

  1. cp ./objs/nginx /usr/sbin/nginx

7、測試新的nginx程序是否正確

  1. nginx -t

8、修改Nginx的 .conf 文件

在監聽443的後面加上http2,如下:
```
server {
    listen 443 ssl http2 default_server;
    server_name www.jiezaizone.cn; 
    ssl on;
    ssl_certificate /etc/nginx/1_jiezaizone.cn_bundle.crt;
    ssl_certificate_key /etc/nginx/2_jiezaizone.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    location / {
        root   /; 
        index  index.html index.htm;
    }
}
```
注:某些服務開啓http2後不能訪問,在http2 後面加上 default_server 就可以了

9、重新加載nginx

  1. nginx -s reload

安裝異常及其解決方法

異常1: 
/usr/bin/ld: /usr/local/lib/libz.a(crc32.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

/usr/local/lib/libz.a: could not read symbols: Bad value 
處理方法: 
cd zlib-1.2.3 //進入zlib目錄

CFLAGS="-O3 -fPIC" ./configure //使用64位元的方法進行編譯

make

異常2: 
/usr/bin/ld: /etc/nginx/openssl-1.0.2e/.openssl/lib/libssl.a(s23_meth.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC 
解決方法: 
cd openssl 
./config -fPIC --prefix=/usr/local/openssl/ enable-shared 
make

測試環境運營系統已經全面支持https

1、倉庫已經push了nginx1.11.1,直接支持http2,可通過下述命令直接拉取下拉使用 
docker pull docker.oa.isuwang.com:5000/system/nginx:1.11.1 
2、在我們的nginx項目http2分支,已經寫好了構建支持http2的nginx dockerdile,可直接下載下拉查看。 
http://git.oa.isuwang.com/isuwang-docker/nginx.git

提問: 
1. HTTPS有併發嗎,如何實現的?一個連接怎麼實現併發呢 
2. http2的長連接是怎麼回事

答: 
1. http2有併發。它支持多路複用,並行雙向字節流的請求和響應,它以“流”的形式在客戶端和服務器間獨立的雙向的交換的幀序列。流具有一些重要的特性: 
- 單個的HTTP/2連接可以包含多個併發打開的流,各個終端多個流的幀可以交叉。 
- 流可以單方面地建立和使用,或由客戶端或服務器共享。 
- 流可以被任何一端關閉。 
- 流中幀的發送順序是值得注意的。接收者以它們收到幀的順序處理。特別的,HEADERS幀和DATA幀在語義上是非常重要的。 
- 流由一個整數標識。流標識符由發起流的一端來賦值。

雖然只有一個TCP連接,卻能夠在這個連接同時處理客戶端和服務端的多個數據傳輸。 
2. HTTP2只有一個TCP連接,它並不像http1.1中的TCP連接一樣,在處理當前傳輸數據後就關閉,而是一直連通的,客戶端和服務端可以通過它持續往返傳輸數據。這個TCP流的傳輸通道,是可以被任何一端給關閉的。

作者:劉榮傑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章