nginx TCP 和 UDP 負(fù)載平衡

  • 自 version 1.9.0 以來新增了 ngx_stream_core_module 模塊,使 nginx 支持四層負(fù)載均衡。這個模塊不僅能實現(xiàn) TCP 和 UDP 轉(zhuǎn)發(fā),還能支持負(fù)載均衡 upstream 配置。默認(rèn)編譯的時候該模塊并未編譯進去,需要編譯的時候添加 --with-stream 參數(shù)使其支持 stream 代理。
  • 由于協(xié)議的不同,UDP 轉(zhuǎn)發(fā)僅會將請求包轉(zhuǎn)發(fā)至目標(biāo),UDP 回復(fù)包將由目標(biāo)機器直接發(fā)出給你的請求端。這個回復(fù)包是不會經(jīng)過轉(zhuǎn)發(fā)端的,所以在你轉(zhuǎn)發(fā)目標(biāo)端 IP 已經(jīng)被不明設(shè)備給屏蔽無法連接的話,這個 UDP 回復(fù)包你還是收不到,這并不是 Nginx 的問題。
  • 請注意,stream 配置不能放到 http 內(nèi),因為stream是通過tcp層轉(zhuǎn)發(fā),而不是 http 轉(zhuǎn)發(fā)
使用Nginx實現(xiàn)TCP反向代理
使用Nginx實現(xiàn)TCP反向代理
  • 下圖是 nginx upstream keepalive 長連接的實現(xiàn)原理。首先每個進程需要一個 connection pool,里面都是長連接,多進程之間是不需要共享這個連接池的。 一旦與后端服務(wù)器建立連接,則在當(dāng)前請求連接結(jié)束之后不會立即關(guān)閉連接,而是把用完的連接保存在一個 keepalive connection pool 里面,以后每次需要建立向后連接的時候,只需要從這個連接池里面找。

  • 如果找到合適的連接的話,就可以直接來用這個連接,不需要重新創(chuàng)建 socket 或者發(fā)起 connect()。這樣既省下建立連接時在握手的時間消耗,又可以避免 TCP 連接的 slow start 慢啟動。如果在 keepalive 連接池找不到合適的連接,那就按照原來的步驟重新建立連接。

  • 如果你的連接池的數(shù)控制在 128 個,總共線程池內(nèi)的線程數(shù)是 128 * nginx worker 個,但因為你要應(yīng)對更多的并發(fā)請求,所以臨時又加了很多的連接,但這臨時的連接是短連接和長連接要看你的 Nginx 版本。那他如何被收回,兩地保證,一點是他會主動去釋放,另一點是 keepalive timeout 的時間。

使用Nginx實現(xiàn)TCP反向代理 使用Nginx實現(xiàn)TCP反向代理

1. 手動編譯

需要注意的是,使用 DockerHub 中的 Nginx 鏡像是不用二次編譯的。

# 下載1.9版本以上的nginx
wget http://nginx.org/download/nginx-1.20.2.tar.gz

# 安裝依賴包
yum install -y gcc glibc gcc-c++ prce-devel openssl-devel pcre-devel
useradd -s /sbin/nologin nginx -M

# 加壓目錄
tar xf nginx-1.10.3.tar.gz && cd nginx-1.20.2

# 手動編譯
./configure \
    --prefix=/usr/local/nginx-1.20.2 \
    --user=nginx \
    --group=nginx \
    --with-http_ssl_module \
    --with-http_stub_status_module \
    --with-stream

# 安裝到系統(tǒng)上
make && make install

# 檢查配置文件
/usr/local/nginx/sbin/nginx -t

2. Nginx TCP 轉(zhuǎn)發(fā)

以下的配置就是 TCP 轉(zhuǎn)發(fā)的最簡配置

  • 我們能很明顯的發(fā)現(xiàn),stream 模塊的配置其實跟 http 模塊很類似。但實際上 stream 模塊與 http 模塊上完全是兩套不同的處理流程。用最簡單的說法就是,http 模塊是基于 Layer7 層的應(yīng)用層處理流程,而 Stream 僅在 Layer4 層上對連接進行處理。

  • 所以 stream 模塊無法像 http 模塊那樣能區(qū)分 vhost 主機名,然而這在 stream 模塊在引入了 ssl 配置之后又能支持了。而且 stream 模塊還能引入 ssl/tls 來對 TCP 連接進行加密。由于 TLS 標(biāo)準(zhǔn)內(nèi)對 SNI 提供了支持,所以又能識別主機名了。在理論上,stream 模塊的端口轉(zhuǎn)發(fā)效率實際上相比 http 模塊的反向代理效率更高。

 
user  nginx;
worker_processes  1;

events {
    worker_connections  1024;
}

stream {
    # 全局配置
    preread_timeout        120s;
    proxy_connect_timeout  120s;
    proxy_protocol_timeout 120s;
    resolver_timeout       120s;
    proxy_timeout          120s;
    tcp_nodelay            on;

    # 設(shè)置日志格式
    log_format proxy '$remote_addr [$time_local] '
                  '$protocol $status $bytes_sent $bytes_received '
                  '$session_time "$upstream_addr" "$upstream_bytes_sent"'
                  '"$upstream_bytes_received" "$upstream_connect_time"';

    access_log /var/log/nginx/stream.access.log proxy;
    error_log  /var/log/nginx/stream.error.log error;

    upstream app_pg {
        hash $remote_addr consistent;
        server 192.168.100.60:5432;
        server 192.168.100.61:5432;
        server 192.168.100.62:5432;
    }

    server {
        # 不指定協(xié)議默認(rèn)是TCP協(xié)議
        listen 127.0.0.1:5432 so_keepalive=on;
        proxy_pass app_pg;
    }

    server{
        # keepalive的可配置參數(shù)差不多有以下幾個:keepidle,keepintvl,keepcnt
        # keepidle為連接保持時間;keepintvl為連接的間隔時間;keepcnt是連接的個數(shù)

        # 下示將idle超時設(shè)置為30分鐘,探測間隔為系統(tǒng)默認(rèn)值,并將探測計數(shù)設(shè)置為10個探測器
        # 實際配置的格式為:so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]
        listen *:3306 so_keepalive=30m::10;
        proxy_connect_timeout 10s;
        proxy_timeout 20s;
        proxy_buffer_size 512k;
        proxy_pass 192.168.100.60:8000;
    }
}

 

  • Nginx實現(xiàn) SSH 轉(zhuǎn)發(fā)
 
user  nginx;
worker_processes  1;

events {
    worker_connections  1024;
}

stream {
    upstream ssh {
            hash $remote_addr consistent;
            server 192.168.1.42:22 weight=5;
       }

    server {
        listen 2222;
        proxy_pass ssh;
       }
}

3. Nginx UDP 轉(zhuǎn)發(fā)

以下的配置就是 UDP 轉(zhuǎn)發(fā)的最簡配置

  • UDP 轉(zhuǎn)發(fā)并不是 stream 模塊一開始就支持的,而是在 1.9.3 版本之后的 stream 模塊才追加了 UDP 轉(zhuǎn)發(fā)支持,所以要配置 UDP 轉(zhuǎn)發(fā)前必須得先確定自己的 Nginx 版本是否達(dá)到了要求。
user  nginx;
worker_processes  1;

events {
    worker_connections  1024;
}

stream {
    # 全局配置
    proxy_timeout 120s;
    tcp_nodelay on;

    # 設(shè)置日志格式
    log_format proxy '$remote_addr [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time "$upstream_addr" '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';

    access_log /var/log/nginx/stream.access.log proxy;
    error_log /var/log/nginx/stream.error.log error;

    # 配置dns負(fù)載均衡
    upstream dns_upstreams {
        server 1.1.1.1:53 weight=1;
        server 1.0.0.1:53 weight=1;        # weight負(fù)載均衡權(quán)重
        server 8.8.8.8:53 weight=1 backup; # backup標(biāo)記為備用服務(wù)器
    }

    server{
        listen 53 udp;
        proxy_responses 1; # UDP協(xié)議專用;期望后端返回給客戶端數(shù)據(jù)包的數(shù)量
        proxy_timeout 20s; # 超時時間
        proxy_pass dns_upstreams;
    }
}
丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清