nginx - http2

最後更新: 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

 

Creative Commons license icon Creative Commons license icon