Nginx使用stream模块分流实现端口复用

使用Nginx复用端口有很多方法,最普遍的方法是在不同的server块中监听同一端口,根据不同的主机名完成分流。本文介绍了一种较新的端口复用方法,它可以方便地对TLS加密的TCP数据进行分流。

1 Nginx stream分流

Nginx一般都工作在应用层,可以通过多个虚拟主机对端口的监听实现分流。其实,Nginx在1.0.9版本以后增加了stream模块,它利用SNI协议(TLS的扩展协议)对同一端口的不同主机转发流量,这一转发过程在传输层完成。

2 分流示例

下面展示了一个stream分流的实例,它根据不同的域名(capa.ink和crps.ink),将请求转发到不同的服务(web1和web2),实现了443端口的复用。

注意,请确保你的nginx中包含stream模块,否则请重新编译安装!

下面展示了stream块的配置方法(位于nginx.conf)。注意stream块与http块并列。

stream {
    map $ssl_preread_server_name $stream_map {
        capa.ink web1;
        crps.ink web2;
    }
    upstream web1 {
        server 127.0.0.1:8000;
    }
    upstream web2 {
        server 127.0.0.1:8001;
    }
    
    #复用443端口
    server {
        listen 443 reuseport;
        listen [::]:443 reuseport;
        proxy_pass $stream_map;
        ssl_preread on;    #重点,一定要加这句
    }
}

此时,nginx应该已经可以根据域名分别将请求分流到8000或8001端口了,我们在配置server块时即可直接监听这个端口。

以下代码展示了一个完整的基于php的网页的配置方案,它对应着上面配置中的"web1"服务,我们只需关心server块中前三行内容。由于该域名的请求已经由stream模块转向8000端口,所以在这里只需要监听8000端口即可。

server {
        listen 8000 ssl http2;
        server_name capa.ink;
        port_in_redirect off;

        ssl_certificate /document/mywebsite/certification/capa.ink_bundle.pem;
        ssl_certificate_key /document/mywebsite/certification/capa.ink.key;

        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        root /document/mywebsite;
        index index.php;

        if (!-e $request_filename) {
                rewrite ^(.*)$ /index.php$1 last;
        }

        location ~ .*\.php(\/.*)*$ {
                root           /document/mywebsite;
                fastcgi_split_path_info ^(.+?.php)(/.*)$;
                fastcgi_pass    127.0.0.1:9005;
                fastcgi_index   index.php;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include         fastcgi_params;
    }
}

3 总结

在Nginx中,用stream块复用端口,与用server块复用端口的区别在于,stream块在传输层就完成了域名的传输,并完成分流;而server块在应用层才读取数据中包含的域名信息,再进行分流。stream可以在加密传输的情况下很方便地复用端口,如果要处理非加密的http协议,那么传统的server块完全能够胜任。

你可能感兴趣的:(vps,nginx,服务器,https)