Nginx代理TCP主要是使用stream模組,這個功能是從1.9.0版本開始的。
我用它來代理Mysql。
一、配置程式碼
stream {
upstream mysqls {
hash $remote_addr consistent;
server 192.168.58.143:3306 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.58.142:3306 weight=1 max_fails=3 fail_timeout=30s;
}
server {
listen 9945;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass mysqls;
}
}
這個就是一個最基本的配置
有幾個注意的地方:
-
stream
的配置必須是和events
同級的,所以我直接就寫在了nginx.conf
主配置檔案中的,這樣就確保了和events
同級。當然也可以單獨寫出來。 - 這裡的
server
裡面是不準寫location
的,所以就不能判斷sss
這樣的路徑來做的。我開始的時候想這樣的,模仿spring
實現的websocket
,後來才意識到,websocket
可以這樣是因為它連線是靠http
協議的,傳輸才靠tcp
的。終於明白了。 -
server
的監聽埠不能和http
的重複。 - 重新載入nginx時候可能會出現錯誤:
[emerg] 30181#0: bind() to 0.0.0.0:8090 failed (13: Permission denied)
這個錯誤是由於SElinux
,關掉這就好了。 - 關閉
SElinux
方法:修改/etc/selinux/config
檔案,將SELINUX=enforcing
改為SELINUX=disabled
重啟之後就好了。
二、用法
語法: listen address:port [ssl] [udp] [proxy_protocol] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
預設值: —
上下文: server
設定方式可以是下面任意一種:
listen 127.0.0.1:12345;
listen *:12345;
listen 12345; # same as *:12345
listen localhost:12345;
IPV6必須加上中括號:
listen [::1]:12345;
listen [::]:12345;
UNIX-domain sockets要寫unix:
字首
listen unix:/var/run/nginx.sock;
ssl
指定連線此埠的連線都是SSL模式
udp
用於處理套接字
proxy_protocol
指定此埠上的所有連線都使用 PROXY protocol協議
backlog=number
限制掛起連線佇列的最大長度(1.9.2)。預設情況下,backlog在FreeBSD,DragonFly BSD和Mac OS X上設定為-1,在其他平臺上設定為511。
bind
表示對一個指定的address:port
對進行單獨的繫結。實是,如果有幾個listen指令具有相同的埠但地址不同,並且其中一個listen指令監聽給定埠(*:port)
的所有地址,nginx將只繫結*:port
。 應該注意,在這種情況下呼叫getsockname()以確定接受連線的地址。 如果使用ipv6only或so_keepalive引數,那麼對於給定的地址:埠對將始終進行單獨的繫結。
ipv6only=on|off
確定偵聽萬用字元地址[::]的IPv6套接字是否只接受IPv6連線,或者是接受IPv6和IPv4連線。 此引數預設處於開啟狀態。 且它只能在啟動時設定一次。
so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]
此引數配置偵聽套接字的“TCP keepalive”
行為。 如果省略此引數,則作業系統的設定將對套接字生效。 如果將其設定為值“on”,則套接字的SO_KEEPALIVE選項將開啟。 如果它設定為值“off”,則套接字的SO_KEEPALIVE選項被關閉。 某些作業系統支援使用TCP_KEEPIDLE,TCP_KEEPINTVL和TCP_KEEPCNT套接字選項在每個套接字上設定TCP保持活動引數。 在這些系統(目前,Linux 2.4+,NetBSD 5+和FreeBSD 9.0-STABLE)上,可以使用keepidle,keepintvl和keepcnt引數配置它們。 可以省略一個或兩個引數,在這種情況下,相應套接字選項的系統預設設定將有效。 例如,
so_keepalive=30m::10
三、相關指令
1.指定preread buffer的大小
Syntax: preread_buffer_size size;
Default:
preread_buffer_size 16k;
Context: stream, server
2.指定preread buffer的超時時間
Syntax: preread_timeout timeout;
Default:
preread_timeout 30s;
Context: stream, server
3.指定完成讀取代理協議頭的超時時間,如果超過這個時間,就關閉連線
Syntax: proxy_protocol_timeout timeout;
Default:
proxy_protocol_timeout 30s;
Context: stream, server
4.配置用於將upstream servers中名稱解析到地址的伺服器
Syntax: resolver address ... [valid=time] [ipv6=on|off];
Default: —
Context: stream, server
This directive appeared in version 1.11.3.
例如:
resolver 127.0.0.1 [::1]:5353;
resolver 127.0.0.1 [::1]:5353 valid=30s;
5.名字解析的超時時間
Syntax: resolver_timeout time;
Default:
resolver_timeout 30s;
Context: stream, server
6.配置伺服器
Syntax: server { ... }
Default: —
Context: stream
7.配置stream伺服器
Syntax: stream { ... }
Default: —
Context: main
8.配置是否允許TCP_NODELAY
選項,這個可以用在客戶端和代理伺服器上
Syntax: tcp_nodelay on | off;
Default:
tcp_nodelay on;
Context: stream, server
9.設定變數的雜湊表容量。
Syntax: variables_hash_bucket_size size;
Default:
variables_hash_bucket_size 64;
Context: stream
10.設定變數的雜湊表最大容量
Syntax: variables_hash_max_size size;
Default:
variables_hash_max_size 1024;
Context: stream
This directive appeared in version 1.11.2.
四、相關變數
-
$binary_remote_addr
:二進位制形式的客戶端地址,對於IPv4地址,值的長度始終為4位元組,對於IPv6地址,值的長度始終為16位元組 -
$bytes_received
:從客戶端接收到的位元組數 -
$bytes_sent
:傳送到客戶端的位元組數 -
$connection
:連線序列號 -
$hostname
:host名稱 -
$msec
:當前時間(秒),以毫秒為單位 -
$nginx_version
:nginx版本 -
$pid
:work process的pid -
$protocol
:和客戶端通訊的協議:TCP或者UDP -
$proxy_protocol_addr
:PROXY協議頭中的客戶端地址,或者為空字串。必須先通過在listen指令中設定proxy_protocol引數才能啟用PROXY協議。 -
$proxy_protocol_port
:PROXY協議頭中的客戶端埠,或者為空字串。必須先通過在listen指令中設定proxy_protocol引數才能啟用PROXY協議。 -
$remote_addr
:客戶端地址 -
$server_addr
:接收連線的伺服器地址。計算此變數的值通常需要一次系統呼叫。 為了避免系統呼叫,listen指令必須指定地址並使用bind引數。 -
$server_port
:接收連線的伺服器埠 -
$session_time
:會話持續時間(秒),以毫秒為單位 -
$time_iso8601
:ISO8610格式的本地時間 -
$time_local
:通用日誌格式的本地時間 -
status
:狀態值。200:會話完成;400:客戶端資料無法解析,例如PROXY協議頭;403:訪問受限;500:內部伺服器錯誤;502:閘道器錯誤;503:服務不可用。