經過咱們會用Nginx的upstream作基於http/https端口的7層負載均衡,因爲Nginx老版本不支持tcp協議,因此基於tcp/udp端口的四層負載均衡通常用LVS或Haproxy來作。至於4層負載均衡和7層負載均衡的區別,能夠參考:http://www.cnblogs.com/kevingrace/p/6137881.html。然而Nginx從1.9.0版本開始,新增長了一個stream模塊,用來實現四層協議的轉發、代理或者負載均衡等,鑑於Nginx在7層負載均衡和web service上的成功,和Nginx良好的框架,stream模塊前景一片光明。官方文檔:http://nginx.org/en/docs/stream/ngx_stream_core_module.htmlphp
Nginx的stream模塊默認不會自帶安裝,須要編譯安裝的時候手動添加上這個模塊。廢話很少說了,下面介紹下一個本身使用stream作四層負載均衡(socket協議代理)的案例:css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
在此以前已經使用Ningx+Keepalived(主從模式)作了7層負載均衡的LB環境,以前編譯的時候,沒有加上這個stream模塊,因此須要後續手動添加該模塊。
因爲Nginx的LB已經有業務跑在上面,能夠選擇平滑添加stream模塊,並不會對線上業務形成多大影響。步驟以下:
1)先在LB的slave從機上進行平滑添加,而後再將vip切換到從機上,隨即在對master主機進行平滑添加該模塊。
2)平滑添加便是從新configure編譯的時候加上--with-stream,接着
make
。
3)千萬注意,
make
以後,不要
make
install
,不然會覆蓋掉以前的配置!!!
--------------------------------------------------------------------------------------------------
因爲本人的LB環境升級了openssl版本,再添加--with-stream從新編譯的時候報了錯誤,具體可參考:
http:
//www
.cnblogs.com
/kevingrace/p/8058535
.html
--------------------------------------------------------------------------------------------------
檢查下,發現nginx沒有安裝stream模塊
[root@external-lb01 ~]
# /data/nginx/sbin/nginx -V
nginx version: nginx
/1
.12.2
built by
gcc
4.4.7 20120313 (Red Hat 4.4.7-18) (GCC)
built with OpenSSL 1.1.0g 2 Nov 2017
TLS SNI support enabled
configure arguments: --prefix=
/data/nginx
--user=www --group=www --with-http_ssl_module --with-http_flv_module
--with-http_stub_status_module --with-http_gzip_static_module --with-pcre
操做以前,必定要備份一下以前的nginx安裝目錄,防止操做失敗進行回滾!
[root@external-lb01 ~]
# cp -r /data/nginx /mnt/nginx.bak
以前的編譯命令是:
[root@external-lb01 vhosts]
# cd /data/software/nginx-1.12.2
[root@external-lb01 nginx-1.12.2]
# ./configure --prefix=/data/nginx --user=www --group=www --with-http_ssl_module
--with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre
如今須要手動添加stream,編譯命令以下:
[root@external-lb01 vhosts]
# cd /data/software/nginx-1.12.2
[root@external-lb01 nginx-1.12.2]
# ./configure --prefix=/data/nginx --user=www --group=www --with-http_ssl_module
--with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream
[root@external-lb01 nginx-1.12.2]
# make
[root@external-lb01 nginx-1.12.2]
# cp -f /data/software/nginx-1.12.2/objs/nginx /data/nginx/sbin/nginx
[root@external-lb01 nginx-1.12.2]
# pkill -9 nginx
[root@external-lb01 nginx-1.12.2]
# /data/nginx/sbin/nginx
檢查下,發現nginx已經安裝了stream模塊了
[root@external-lb01 nginx-1.12.2]
# /data/nginx/sbin/nginx -V
nginx version: nginx
/1
.12.2
built by
gcc
4.4.7 20120313 (Red Hat 4.4.7-18) (GCC)
built with OpenSSL 1.1.0g 2 Nov 2017
TLS SNI support enabled
configure arguments: --prefix=
/data/nginx
--user=www --group=www --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-openssl=
/usr/local/ssl
======================================================================================================================
stream的4層負載均衡和upstream的7層負載均衡能夠共同配置在nginx中,stream模塊用法和http模塊差很少,關鍵的是語法幾乎一致。
具體以下:
[root@external-lb01 ~]
# cat /data/nginx/conf/nginx.conf
user www;
worker_processes 8;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 65535;
}
stream {
upstream kk5 {
server 10.0.58.22:5100;
server 10.0.58.23:5100;
}
upstream kk5http {
server 10.0.58.22:8000;
server 10.0.58.23:8000;
}
upstream kk5https {
server 10.0.58.22:8443;
server 10.0.58.23:8443;
}
server {
listen 5100;
proxy_connect_timeout 1s;
proxy_pass kk5;
}
server {
listen 8000;
proxy_connect_timeout 1s;
proxy_pass kk5http;
}
server {
listen 8443;
proxy_connect_timeout 1s;
proxy_pass kk5https;
}
}
http {
include mime.types;
default_type application
/octet-stream
;
charset utf-8;
######
## set access log format
######
log_format main
'$remote_addr $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'$http_user_agent $http_x_forwarded_for $request_time $upstream_response_time $upstream_addr $upstream_status'
;
#######
## http setting
#######
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
proxy_cache_path
/var/www/cache
levels=1:2 keys_zone=mycache:20m max_size=2048m inactive=60m;
proxy_temp_path
/var/www/cache/tmp
;
fastcgi_connect_timeout 3000;
fastcgi_send_timeout 3000;
fastcgi_read_timeout 3000;
fastcgi_buffer_size 256k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
#
client_header_timeout 600s;
client_body_timeout 600s;
# client_max_body_size 50m;
client_max_body_size 100m;
client_body_buffer_size 256k;
gzip
on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 9;
gzip_types text
/plain
application
/x-javascript
text
/css
application
/xml
text
/javascript
application
/x-httpd-php
;
gzip_vary on;
## includes vhosts
include vhosts/*.conf;
}
[root@external-lb01 ~]
# cd /data/nginx/conf/vhosts/
[root@external-lb01 vhosts]
# ls
-rw-r-xr-- 1 root root 889 12月 26 15:18 bpm.kevin.com.conf
-rw-r-xr-- 1 root root 724 12月 26 14:38 mobi.kevin.com.conf
[root@external-lb01 vhosts]
# cat bpm.kevin.com.conf
upstream os-8080 {
ip_hash;
server 10.0.58.20:8080 max_fails=3 fail_timeout=15s;
server 10.0.58.21:8080 max_fails=3 fail_timeout=15s;
}
server {
listen 80;
server_name bpm.kevin.com;
access_log
/data/nginx/logs/bpm
.kevin.com-access.log main;
error_log
/data/nginx/logs/bpm
.kevin.com-error.log;
location / {
proxy_pass http:
//os-8080
;
proxy_set_header Host $host;
proxy_redirect http:
//os-8080/
http:
//bpm
.kevin.com/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
}
error_page 500 502 503 504
/50x
.html;
location =
/50x
.html {
root html;
}
}
[root@external-lb01 vhosts]
# cat mobi.kevin.com.conf
upstream mobi_cluster{
server 10.0.54.20:8080;
}
server {
listen 80;
server_name mobi.kevin.com;
access_log
/data/nginx/logs/mobi
.kevin.com-access.log main;
error_log
/data/nginx/logs/mobi
.kevin.com-error.log;
location / {
proxy_pass http:
//mobi_cluster
;
proxy_set_header Host $host;
proxy_redirect http:
//mobi_cluster/
http:
//mobi
.kevin.com/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504
/50x
.html;
location =
/50x
.html {
root html;
}
}
關閉防火牆,不然要依次打開如上配置中的端口!
[root@external-lb01 vhosts]
# /data/nginx/sbin/nginx -s reload
重啓nginx後,發現http端口80、8080、8000、8443都起來了(
lsof
命令能夠查看到),而tcp
/udp
端口5100沒有起來,這是正常的。
|
==========順便總結下Nginx的四大模塊——proxy、headers、upstream、stream模塊梳理=========html
1、ngx_http_proxy_module模塊前端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
1)proxy_pass URL;
Context: location,
if
in
location, limit_except
注意:proxy_pass後面的路徑不帶uri時,其會將location的uri傳遞給後端主機
server {
…
server_name HOSTNAME;
location
/uri/
{
proxy http:
//hos
[:port];
}
…
}
http:
//HOSTNAME/uri
–> http:
//host/uri
proxy_pass後面的路徑是一個uri時,其會將location的uri替換爲proxy_pass的uri
server {
…
server_name HOSTNAME;
location
/uri/
{
proxy http:
//host/new_uri/
;
}
…
}
http:
//HOSTNAME/uri/
–> http:
//host/new_uri/
若是location定義其uri時使用了正則表達式的模式,則proxy_pass以後必須不能使用uri; 用戶請求時傳遞的uri將直接附加代理到的服務的以後
server {
…
server_name HOSTNAME;
location ~|~*
/uri/
{
proxy http:
//host
;
}
…
}
http:
//HOSTNAME/uri/
–> http:
//host/uri/
2)proxy_set_header field value;
設定發日後端主機的請求報文的請求首部的值;Context: http, server, location
proxy_set_header X-Real-IP $remote_addr;
$remote_addr:記錄的是上一臺主機的IP,而上一臺主機有可能也是代理服務器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
$proxy_add_x_forwarded_for:記錄的是源IP地址
在http客戶端還有修改
/etc/httpd/conf/httpd
.conf文件
LogFormat
"%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
combined
經過上述方法則能夠在後端主機上記錄真實的httpd資源請求者,而再也不是隻記錄前端代理服務器的IP地址
3)proxy_cache_path
定義可用於proxy功能的緩存;Context: http
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=
time
]
[max_size=size] [manager_files=number] [manager_sleep=
time
] [manager_threshold=
time
] [loader_files=number]
[loader_sleep=
time
] [loader_threshold=
time
] [purger=on|off] [purger_files=number] [purger_sleep=
time
] [purger_threshold=
time
];
proxy_cache_path
/var/cache/nginx/proxy_cache
levels=1:2:1 keys_zone=gmtest:20M max_size=1G;
4)proxy_cache zone | off;
指明要調用的緩存,或關閉緩存機制;Context: http, server, location
proxy_cache gmtest;
5)proxy_cache_key string;
緩存中用於「鍵」的內容;
默認值:proxy_cache_key $scheme$proxy_host$request_uri;
建議定義成方法和url
6)proxy_cache_valid [code …]
time
;
定義對特定響應碼的響應內容的緩存時長;
定義在http{…}中;
proxy_cache_path
/var/cache/nginx/proxy_cache
levels=1:1:1 keys_zone=gmtest:20m max_size=1g;
定義在須要調用緩存功能的配置段,例如server{…},或者location中;
proxy_cache gmtest;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 1h;
proxy_cache_valid any 1m;
7)proxy_cache_use_stale
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403
| http_404 | off …;
Determines
in
which
cases a stale cached response can be used when an error occurs during communication with the proxied server.
後端服務器的故障在那種狀況下,就使用緩存的功能對客戶的進行返回
8)proxy_cache_methods GET | HEAD | POST …;
If the client request method is listed
in
this directive
then
the response will be cached. 「GET」 and 「HEAD」 methods are always
added to the list, though it is recommended to specify them explicitly.
默認方法就是GET HEAD方法
9)proxy_hide_header field;
By default, nginx does not pass the header fields 「Date」, 「Server」, 「X-Pad」, and 「X-Accel-…」 from the response of a proxied server
to a client. The proxy_hide_header directive sets additional fields that will not be passed.
10)proxy_connect_timeout
time
;
Defines a timeout
for
establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75
seconds.
默認爲60s
11)buffer相關的配置
a:proxy_buffer_size size;
Sets the size of the buffer used
for
reading the first part of the response received from the proxied server. This part usually contains
a small response header. By default, the buffer size is equal to one memory page.
默認爲4k|8k
b:proxy_buffering on | off;
Enables or disables buffering of responses from the proxied server.
默認爲on
c:proxy_buffers number size;
Sets the number and size of the buffers used
for
reading a response from the proxied server,
for
a single connection. By default, the buffer size is equal to one memory page.
默認爲8 4k|8k
d:proxy_busy_buffers_size size;
When buffering of responses from the proxied server is enabled, limits the total size of buffers that can be busy sending a response to the client
while
the response is not yet fully
read
.
默認爲8k|16k
|
2、ngx_http_headers_module模塊java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
The ngx_http_headers_module module allows adding the 「Expires」 and 「Cache-Control」 header fields, and arbitrary fields,
to a response header.
向由代理服務器響應給客戶端的響應報文添加自定義首部,或修改指定首部的值;
1)add_header name value [always];
添加自定義首部;
add_header X-Via $server_addr;
經由的代理服務器地址
add_header X-Accel $server_name;
2)expires [modified]
time
;
expires epoch | max | off;
用於定義Expire或Cache-Control首部的值;
能夠把服務器定義的緩存時長修改了;
|
3、ngx_http_upstream_module模塊node
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
The ngx_http_upstream_module module is used to define
groups
of servers that can be referenced by the proxy_pass, fastcgi_pass,
uwsgi_pass, scgi_pass, and memcached_pass directives.
1)upstream name { … }
定義後端服務器組,會引入一個新的上下文;Context: http
upstream httpdsrvs {
server …
server…
…
}
2)server address [parameters];
在upstream上下文中server成員,以及相關的參數;Context: upstream
address的表示格式:
unix:
/PATH/TO/SOME_SOCK_FILE
IP[:PORT]
HOSTNAME[:PORT]
parameters:
weight=number
權重,默認爲1;默認算法是wrr
max_fails=number
失敗嘗試最大次數;超出此處指定的次數時,server將被標記爲不可用
fail_timeout=
time
設置將服務器標記爲不可用狀態的超時時長
max_conns
當前的服務器的最大併發鏈接數
backup
將服務器標記爲「備用」,即全部服務器均不可用時此服務器才啓用
down
標記爲「不可用」
先在nginx前端配置down,而後在下架後端服務器,上架新的web程序,而後上架,在修改配置文件立馬的down
3)least_conn;
最少鏈接調度算法,當server擁有不一樣的權重時其爲wlc
要在後端服務器是長鏈接時,效果纔好,好比mysql
4)ip_hash;
源地址
hash
調度方法
5)
hash
key [consistent];
基於指定的key的
hash
表來實現對請求的調度,此處的key能夠直接文本、變量或兩者的組合
做用:將請求分類,同一類請求將發往同一個upstream server
If the consistent parameter is specified the ketama consistent hashing method will be used instead.
示例:
hash
$request_uri consistent;
hash
$remote_addr;
hash
$cookie_name; 對同一瀏覽器的請求,發往同一個upstream server
6)keepalive connections;
爲每一個worker進程保留的空閒的長鏈接數量
nginx的其它的二次發行版:
tengine
OpenResty
1.9版本以後能夠反代tcp/udp的協議,基於stream模塊,工做與傳輸層
|
HTTP負載均衡,也就是咱們一般全部"七層負載均衡",工做在第七層"應用層"。而TCP負載均衡,就是咱們一般所說的"四層負載均衡",工做在"網絡層"和"傳輸層"。例如,LVS(Linux Virtual Server,Linux虛擬服務)和F5(一種硬件負載均衡設備),也是屬於"四層負載均衡"mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
nginx-1.9.0 已發佈,該版本增長了stream 模塊用於通常的TCP 代理和負載均衡,ngx_stream_core_module 這個模塊在1.90版本後將被啓用。可是並不會默認安裝,
須要在編譯時經過指定 --with-stream 參數來激活這個模塊。
1)配置Nginx編譯文件參數
.
/configure
--with-http_stub_status_module --with-stream
------------------------------------------------------------------
2)編譯、安裝,
make
&&
make
install
------------------------------------------------------------------
3)配置nginx.conf文件
stream {
upstream kevin {
server 192.168.10.10:8080;
#這裏配置成要訪問的地址
server 192.168.10.20:8081;
server 192.168.10.30:8081;
#須要代理的端口,在這裏我代理一一個kevin模塊的接口8081
}
server {
listen 8081;
#須要監聽的端口
proxy_timeout 20s;
proxy_pass kevin;
}
}
建立最高級別的stream(與http同一級別),定義一個upstream組 名稱爲kevin,由多個服務組成達到負載均衡 定義一個服務用來監聽TCP鏈接(如:8081端口),
而且把他們代理到一個upstream組的kevin中,配置負載均衡的方法和參數爲每一個server;配置些如:鏈接數、權重等等。
首先建立一個server組,用來做爲TCP負載均衡組。定義一個upstream塊在stream上下文中,在這個塊裏面添加由server命令定義的server,指定他的IP地址和
主機名(可以被解析成多地址的主機名)和端口號。下面的例子是創建一個被稱之爲kevin組,兩個監聽1395端口的server ,一個監聽8080端口的server。
upstream kevin {
server 192.168.10.10:8080;
#這裏配置成要訪問的地址
server 192.168.10.20:8081;
server 192.168.10.30:8081;
#須要代理的端口,在這裏我代理一一個kevin模塊的接口8081
}
須要特別注意的是:
你不能爲每一個server定義協議,由於這個stream命令創建TCP做爲整個 server的協議了。
配置反向代理使Nginx可以把TCP請求從一個客戶端轉發到負載均衡組中(如:kevin組)。在每一個server配置塊中 經過每一個虛擬server的server的配置信息和在
每一個server中定義的監聽端口(客戶端需求的代理端口號,如我推流的的是kevin協議,則端口號爲:8081)的配置信息和proxy_passs 命令把TCP通訊發送到
upstream的哪一個server中去。下面咱們將TCP通訊發送到kevin 組中去。
server {
listen 8081;
#須要監聽的端口
proxy_timeout 20s;
proxy_pass kevin;
}
固然咱們也能夠採用單一的代理方式:
server {
listen 8081;
#須要監聽的端口
proxy_timeout 20s;
proxy_pass 192.168.10.30:8081;
#須要代理的端口,在這裏我代理一一個kevin模塊的接口8081
}
------------------------------------------------------------------
4)改變負載均衡的方法:
默認nginx是經過輪詢算法來進行負載均衡的通訊的。引導這個請求循環的到配置在upstream組中server端口上去。 由於他是默認的方法,這裏沒有輪詢命令,
只是簡單的建立一個upstream配置組在這兒stream山下文中,並且在其中添加server。
a)least-connected :對於每一個請求,nginx plus選擇當前鏈接數最少的server來處理:
upstream kevin {
least_conn;
server 192.168.10.10:8080;
#這裏配置成要訪問的地址
server 192.168.10.20:8081;
server 192.168.10.30:8081;
#須要代理的端口,在這裏我代理一一個kevin模塊的接口8081
}
b)least
time
:對於每一個連接,nginx pluns 經過幾點來選擇server的: 最底平均延時:經過包含在least_time命令中指定的參數計算出來的:
connect:鏈接到一個server所花的時間
first_byte:接收到第一個字節的時間
last_byte:所有接收完了的時間 最少活躍的鏈接數:
upstream kevin {
least_time first_byte;
server 192.168.10.10:8080;
#這裏配置成要訪問的地址
server 192.168.10.20:8081;
server 192.168.10.30:8081;
#須要代理的端口,在這裏我代理一一個kevin模塊的接口8081
}
c)普通的
hash
算法:nginx plus選擇這個server是經過user_defined 關鍵字,就是IP地址:$remote_addr;
upstream kevin {
hash
$remote_addr consistent;
server 192.168.10.10:8080 weight=5;
#這裏配置成要訪問的地址
server 192.168.10.20:8081 max_fails=2 fail_timeout=30s;
server 192.168.10.30:8081 max_conns=3;
#須要代理的端口,在這裏我代理一一個kevin模塊的接口8081
}
|
=================Nginx的TCP負載均衡====================nginx
Nginx的TCP負載均衡的執行原理
當Nginx從監聽端口收到一個新的客戶端連接時,馬上執行路由調度算法,得到指定須要鏈接的服務IP,而後建立一個新的上游鏈接,鏈接到指定服務器。web
TCP負載均衡支持Nginx原有的調度算法,包括Round Robin(默認,輪詢調度),哈希(選擇一致)等。同時,調度信息數據也會和健壯性檢測模塊一塊兒協做,爲每一個鏈接選擇適當的目標上游服務器。若是使用Hash負載均衡的調度方法,你可使用$remote_addr(客戶端IP)來達成簡單持久化會話(同一個客戶端IP的鏈接,老是落到同一個服務server上)。
和其餘upstream模塊同樣,TCP的stream模塊也支持自定義負載均和的轉發權重(配置「weight=2」),還有backup和down的參數,用於踢掉失效的上游服務器。max_conns參數能夠限制一臺服務器的TCP鏈接數量,根據服務器的容量來設置恰當的配置數值,尤爲在高併發的場景下,能夠達到過載保護的目的。
Nginx監控客戶端鏈接和上游鏈接,一旦接收到數據,則Nginx會馬上讀取而且推送到上游鏈接,不會作TCP鏈接內的數據檢測。Nginx維護一分內存緩衝區,用於客戶端和上游數據的寫入。若是客戶端或者服務端傳輸了量很大的數據,緩衝區會適當增長內存的大小。
當Nginx收到任意一方的關閉鏈接通知,或者TCP鏈接被閒置超過了proxy_timeout配置的時間,鏈接將會被關閉。對於TCP長鏈接,咱們更應該選擇適當的proxy_timeout的時間,同時,關注監聽socke的so_keepalive參數,防止過早地斷開鏈接。
Nginx的TCP負載均衡服務健壯性監控
TCP負載均衡模塊支持內置健壯性檢測,一臺上游服務器若是拒絕TCP鏈接超過proxy_connect_timeout配置的時間,將會被認爲已經失效。在這種狀況下,Nginx馬上嘗試鏈接upstream組內的另外一臺正常的服務器。鏈接失敗信息將會記錄到Nginx的錯誤日誌中。
若是一臺服務器,反覆失敗(超過了max_fails或者fail_timeout配置的參數),Nginx也會踢掉這臺服務器。服務器被踢掉60秒後,Nginx會偶爾嘗試重連它,檢測它是否恢復正常。若是服務器恢復正常,Nginx將它加回到upstream組內,緩慢加大鏈接請求的比例。
之所"緩慢加大",由於一般一個服務都有"熱點數據",也就是說,80%以上甚至更多的請求,實際都會被阻擋在"熱點數據緩存"中,真正執行處理的請求只有不多的一部分。在機器剛剛啓動的時候,"熱點數據緩存"實際上尚未創建,這個時候爆發性地轉發大量請求過來,極可能致使機器沒法"承受"而再次掛掉。以mysql爲例子,咱們的mysql查詢,一般95%以上都是落在了內存cache中,真正執行查詢的並很少。
其實,不管是單臺機器或者一個集羣,在高併發請求場景下,重啓或者切換,都存在這個風險,解決的途徑主要是兩種:
1)請求逐步增長,從少到多,逐步積累熱點數據,最終達到正常服務狀態。
2)提早準備好"經常使用"的數據,主動對服務作"預熱",預熱完成以後,再開放服務器的訪問。
TCP負載均衡原理上和LVS等是一致的,工做在更爲底層,性能會高於原來HTTP負載均衡很多。可是,不會比LVS更爲出色,LVS被置於內核模塊,而Nginx工做在用戶態,並且,Nginx相對比較重。另一點,使人感到很是惋惜,這個模塊居然是個付費功能