在 Nginx 和 Golang web 上抢先体验 QUIC

QUIC(Quick UDP Internet Connection)是谷歌推出的一套基于 UDP 的传输协议,它实现了 TCP + HTTPS + HTTP/2 的功能,目的是保证可靠性的同时降低网络延迟。QUIC 是使用 UDP 协议,可以与原来的 TCP 服务不冲突。

QUIC

Nginx + QUIC

Nginx 官方还没支持 QUIC ,Cloudflare 给 nginx 做了一个补丁,但说仅支持 1.16.x 。我用nginx 目前最新稳定版 1.17.9 也没问题。

下面是安装的过程,系统 ubuntu/debian

安装依赖

1
apt-get install build-essential automake autoconf make git

安装 pcre,支持重写rewrite功能

源码下载地址: https://ftp.pcre.org/pub/pcre/

1
2
3
4
5
wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz 
tar -zxvf pcre-8.44.tar.gz
cd pcre-8.44
./configure
make && make install

安装 zlib, 支持 gzip 压缩

源码下载地址: http://zlib.net

1
2
3
4
5
wget http://zlib.net/zlib-1.2.11.tar.gz
tar -zxvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure
make && make install

安装 nginx

源码地址: http://nginx.org/en/download.html

1
2
wget http://nginx.org/download/nginx-1.17.9.tar.gz
tar -zxvf nginx-1.17.9.tar.gz

下载 nginx quic 补丁

1
git clone --recursive https://github.com/cloudflare/quiche

还安装 golang 、rust 环境

1
2
wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.14.linux-amd64.tar.gz

添加环境变量 /etc/profile

1
export PATH=$PATH:/usr/local/go/bin

安装 cargo

1
curl https://sh.rustup.rs -sSf | sh

开始编译

1
2
3
4
5
6
7
8
9
10
11
12
13
cd nginx-1.17.9
patch -p01 < ../quiche/extras/nginx/nginx-1.16.patch

./configure --prefix=/usr/local/nginx \
   	--with-http_ssl_module              	\
   	--with-http_v2_module               	\
   	--with-http_v3_module               	\
   	--with-openssl=../quiche/deps/boringssl \
   	--with-quiche=../quiche \
    --with-pcre=/root/downloads/pcre-8.44 \
    --with-zlib=/root/downloads/zlib-1.2.11 

make && make install

配置,在 nginx.confserver 里添加下面内容,还要先申请证书,改为自己的证书路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
    # Enable QUIC and HTTP/3.
    listen 443 quic reuseport;

    # Enable HTTP/2 (optional).
    listen 443 ssl http2;

    listen       80;
    server_name  localhost;

    ssl_certificate  /root/example.com.cer;
    ssl_certificate_key  /root/example.com.key;

    # Enable all TLS versions (TLSv1.3 is required for QUIC).
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    
    # Add Alt-Svc header to negotiate HTTP/3.
    add_header alt-svc 'h3-23=":443"; ma=86400';

    ...
}

启动 nginx

1
/usr/local/nginx/sbin/nginx

查看nginx 监听端口

1
2
3
4
# netstat -peanut | grep  nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          499991     27365/nginx: master 
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      0          499990     27365/nginx: master 
udp        0      0 0.0.0.0:443             0.0.0.0:*                           0          499989     27365/nginx: master 

安装过程挺久,还需要有好的网络环境,还要安装 go 和 rust 相关库。还不如直接用 go

go + QUIC

caddy 很方便,但caddy 1 已经放弃参数 -quic ,将在 caddy 2 里支持,caddy 2 使用库 lucas-clemente/quic-go ,因此就直接使用 lucas-clemente/quic-go,先体验。

写一个go脚本

Go:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
	"github.com/lucas-clemente/quic-go/http3"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		_, _ = w.Write([]byte("hello quic"))
	})

	_ = http3.ListenAndServe("0.0.0.0:443",
		"/root/example.com.cer",
		"/root/example.com.key", nil)
}

编译后运行,查看端口:

1
2
3
# netstat -peanut | grep  http3server
tcp6       0      0 :::443                  :::*                    LISTEN      0          501623     27472/./http3server        
udp6       0      0 :::443                  :::*                                0          501622     27472/./http3server 

协议是 tcp6udp6 ,但不影响 v4 的访问,nginx 是 v4。

总结

如果嵌入到单个应用,还是 go 使用比较方便。现在相关库还在完善,不急于部署到生产环境,虽然google 自家已经在很多产品使用 quic

google quic

参考

本文网址: https://pylist.com/topic/207.html 转摘请注明来源

Suggested Topics

golang 计算大文件md5

以前介绍过用python 计算大文件的md5 值,这里将介绍使用 golang 计算大文件md5...

golang 缓存模版的方法

这是官方使用的方法,实例初始化时把所有模版渲染后缓存到 templates,后续使用ExecuteTemplate 方法来使用特定的模版...

Golang 版 supervisord 使用记录

python 版经常出现一些错误,比如 supervisor.sock 文件找不到的错误。懒得去整,试试二进制的 supervisord ,用 Go 语言编写。...

使用Golang selenium WebDriver 自动登录微博

有时候在Golang 程序里需要读取微博的某个页面内容,提示需要登录。最简单的方法是在浏览器里登录后,直接复制Cookie 的内容,然后 http 请求带上Cookie。这样会有人工介入,不是很方便,这里借用 selenium WebDriver 来打开微博登录页面,然后自动填入用户名与密码。...

Golang 实现新闻网页提取正文内容

前段时间接触到新闻页面的提取问题,发现了python 实现的 gne ,测试一段时间,效果很好,但还不适合个人的需求,于是就用 go 来实现类似的功能。...

Golang结合OpenCC实现高效的中文简体繁体互转

之前在页面中使用简体转繁体的功能一般是使用JS对页面进行字典替换,这样可以解决大部分问题,但要进行精确的转换,才发现简繁体的转换是个复杂的过程。幸好有个非常棒的繁体转简体开源项目OpenCC可以很好的工作。...

一个简单高效的LRU 缓存,golang 实现

LRU(Least recently used,最近最少使用)是根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。...

Leave a Comment

2 thoughts on "在 Nginx 和 Golang web 上抢先体验 QUIC"

#1 李哈哈 says:

您好,在nginx.conf中加入以上内容,在启动nginx时提示配置文件中的quic为无效参数,想请教您这种情况怎么解决?谢谢

#2 pylist says:

@李哈哈 前提是从源码编译nginx,./configure 要包含相关内容。输出你的 configure 看看。