最後更新: 2018-11-19
介紹
* use of binary message framing
* allows prioritization of requests
* allows interleaving of request and response messages on the same connection
* uses an efficient coding for HTTP header fields
* interaction mode whereby a server can push responses to a client
The basic protocol unit in HTTP/2 is a frame
- HEADERS frames
- DATA frames
- SETTINGS frames
- WINDOW_UPDATE frames
- PUSH_PROMISE frames
目錄
- tengine - HTTP2
- Build nginx with http2 (Centos 7)
- Static compile
- Server Push
tengine - HTTP2
Tengine 在 Version 2.1.3 support http2
下載
git clone https://github.com/alibaba/tengine.git
cd tengine
git checkout 2.1.3
Compile
./configure ... --with-http_ssl_module --with-http_v2_module --enable-mods-static=all
Remark
"--enable-mods-static=all" 係為了方便安裝, compile 後 size 有成 14M
make
安裝
which nginx
/opt/tengine/sbin/nginx
cp -f objs/nginx /opt/tengine/sbin/nginx
設定
listen 443 ssl http2 fastopen=64;
fastopen
Enables “TCP Fast Open” for the listening socket (不用等 three-way handshake)
It works by using a TFO cookie. (a cryptographic cookie)
當 Client 與 Server 之前有溝通過後, 下次 SYN 時會發送之前建立好的 TFO cookie
Server 就不等 Client 的 SYN-ACK 就放 Data
no Web browsers used it by default (@2020)
測試
- Firefox Plugin: SPDY indicator
- Chrome Dev Tool (F12) → Network → Protocol 會見到係 h2
Build nginx with http2 (Centos 7)
ALPN (Application-Layer Protocol Negotiation) is a TLS extension
that includes the protocol negotiation within the exchange of hello messages.
* 舊版 OpenSSL 用 NPN(Next Protocol Negotiation), 新版用 ALPN
# Version
* Nginx 1.9.5+
* OpenSSL 1.0.2+
nginx -v
openssl version
# Openssl
cd /usr/src
wget https://www.openssl.org/source/openssl-1.0.2k.tar.gz
tar -zxf openssl-1.0.2k.tar.gz
# Nginx
wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -zxf nginx-1.10.3.tar.gz
# 安裝所需 package
yum install -y pcre-devel zlib-devel
build.sh
#!/bin/bash ./configure --prefix=/opt/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-openssl=/usr/src/openssl-1.0.2k \ --with-http_stub_status_module
Static Compile
nginx-build - provides a command to build nginx seamlessly.
https://github.com/cubicdaiya/nginx-build
https://github.com/cubicdaiya/nginx-build/releases
Testing Version: v0.9.14
Usage
mkdir nginx
cd nginx
wget https://github.com/cubicdaiya/nginx-build/releases/download/....
tar -zxf nginx-build-linux-amd64-0.9.14.tar.gz
# check version
./nginx-build -version
nginx-build 0.9.14 Compiler: gc go1.7.4 Copyright (C) 2014-2016 Tatsuhiko Kubo <[email protected]>
# support build nginx version
./nginx-build -versions
# set build version
-v 1.10.3
config.txt
./configure \ --prefix=/opt/nginx \ --sbin-path=/usr/sbin/nginx \ --pid-path=/run/nginx.pid \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --lock-path=/run/lock/subsys/nginx \ --user=nginx --group=nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-openssl=/usr/src/openssl-1.0.2k \ --with-http_stub_status_module \ --without-http_scgi_module \ --without-http_uwsgi_module \ --without-http_memcached_module \ --with-cc-opt='-O2'
# Embedding X statically
- pcre
- openssl
- zlib
# Build & Install
./nginx-build -d work -v 1.10.3 -c config.txt
-d # working directory
cd work/nginx/1.10.3/nginx-1.10.3
make install
# Static file size
ll -h /opt/nginx/sbin/nginx
-rwxr-xr-x 1 root root 8.5M Mar 2 16:48 /opt/nginx/sbin/nginx
# logrotate
/etc/logrotate.d/nginx
/var/log/nginx/*log { create 0644 nginx nginx daily rotate 10 missingok notifempty compress sharedscripts postrotate /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true endscript }
Server Push
HTTP/2 server push support feature # nginx 1.13.9
減小http 請求的方案
(1) 把圖片改成 Base64 編碼的 Data URL
(2) Link header: <link rel="preload" href="/styles.css" as="style"> (沒有減少 HTTP 請求)
(3) Server Push
Push
Content in the HTTP page cache in the browser is used in preference to content in the push cache, even if the pushed content is fresher.
HTTP/2 connections can be shared among different page loads. A resource that is pushed as a result of one page load can be used when requested in a different page load.
server { listen 443 ssl http2 default_server; ssl_certificate ssl/certificate.pem; ssl_certificate_key ssl/key.pem; http2_push_preload on; root /usr/share/nginx/html; index index.html index.htm; location = /demo.html { add_header Set-Cookie "session=1"; add_header Link $resources; } # 不論什麼情況都 push location / { http2_push /style.css; http2_push /example.png; } } map $http_cookie $resources { "~*session=1" ""; default "</style.css>; as=style; rel=preload"; }
Verifying
with Developer Tools (Google Chrome)
Initiator: "Push /demo.html"
CLI: nghttp
"http2_push_preload"
Backend Push
backend 在回應時, 在 http header 加入
Link: </styles.css>; rel=preload; as=style
原理
intercepting Link preload headers, then pushing the resources identified in these headers.
(When NGINX is operating as a proxy (for HTTP, FastCGI, or other traffic types))
# Be absolute paths
Link: </style.css>; as=style; rel=preload, </favicon.ico>; as=image; rel=preload
# Resource is not pushed (Preload Hints)
Link: </nginx.png>; as=image; rel=preload; nopush
加 Cookie 原因
The HTTP/2 specification doesn 't address the challenge of determining whether or not to push resources.
(to push resources to clients only on their first visit to the site. )
Other
https://datahunter.org/apache_http2