在日常运维工作中,运维人员会时常使用到nginx的反向代理,负载均衡以及缓存等功能来优化web服务性能。
废话不多说,下面对测试环境下的nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)搭建过程做一记录:
一、后端的Real Server的准备
两台RS服务器(192.168.1.104/192.168.1.105)要事先配置好nginx。
并且nginx访问均是用ip访问即可,方便实验效果!
二、nginx代理服务器192.168.1.103(假设外网ip是111.112.114.23)的配置
1.nginx反向代理和缓存
0)安装依赖软件(如果是ubuntu系统,则sudo apt-get update && sudo apt-get upgrade && sudo apt-get install libpcre3 libpcre3-dev zlib1g-dev libssl-dev build-essential openssl libssl0.9.8 libssl-dev)
[root@node1 ~]# yum install -y pcre pcre-devel openssl openssl-devel gcc
1)首先添加用户nginx,实现以之运行nginx服务进程:
[root@node1 ~]# groupadd -r nginx
[root@node1 ~]# useradd -r -g nginx -s /bin/false -M nginx #-M参数表示创建用户时不创建用户家目录
2)接着开始编译和安装:
[root@node1 ~]# cd /usr/loca/src
[root@node1 src]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@node1 src]# tar -zxvf nginx-1.8.0.tar.gz
[root@node1 src]# cd nginx-1.8.0
[root@node1 nginx-1.8.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre
[root@node1 src]# make && make install
#以上编译安装nginx后,--http-client-body-temp-path、--http-proxy-temp-path、--http-fastcgi-temp-path、--http-uwsgi-temp-path、--http-scgi-temp-path默认的路径就在/usr/local/nginx下,分别是client_body_temp、proxy_temp、fastcgi_temp、scgi_temp、uwsgi_temp
[root@node1 src]# cd /usr/local/nginx/
[root@node1 nginx]# ls
conf html logs sbin
[root@node1 nginx]# /usr/local/nginx/sbin/nginx //nginx启动后,就会出现下面的目录
[root@node1 nginx]# ls /usr/local/nginx/
client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp
3)反代的实现,和缓存的开启(可参考:nginx缓存配置的操作记录梳理)
[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#要想开启nginx的缓存功能,需要添加此处的两行内容!
#这一行分别表示:定义缓存存储目录,手动创建;缓存级别,表示缓存目录的第一级目录是1个字符,第二级目录是2个字符;内核中建立用于缓存缓存数据源数据的空间,查找缓存的时候,先从这个内核空间中找到,缓存数据的源数据,然后再到对应目录中查找缓存;这一行分别表示:缓存空间最大值;缓存的数据,60分钟内没有被访问过就删除
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;
server {
listen 80;
server_name localhost;
location / {
#root html;
#index index.html index.htm;
proxy_pass http://192.168.1.104/; #代理哪个web服务器
proxy_cache mycache; #内存缓存源数据空间名字,对应我们前面的设定
proxy_cache_valid 200 302 60m; #页面返回码为200 302 的缓存60分
proxy_cache_valid 404 1m; #页面错误响应吗404缓存时间1分
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
[root@node1 src]# mkdir /var/www/cache
[root@node1 src]# /usr/local/nginx/sbin/nginx
4)验证结果
访问http://111.112.114.23,则显示的是http://192.168.1.104的访问结果(如上配置,RS2的反向代理类似)
---------------------------------------------------------------------------------------------------------
再看如下的一个实例配置(nginx.conf文件中已开启缓存功能)(max_fails默认值为1,fail_timeout默认值为10s,连接失败的情形由proxy_next_upstream 指定)
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
|
upstream LB-WWW {
ip_hash;
server 192.168.1.101:80 max_fails=3 fail_timeout=30s weight=100;
#max_fails = 3 为允许失败的次数,默认值为1
server 192.168.1.102:80 max_fails=3 fail_timeout=30s weight=100;
#fail_timeout = 30s(也可以是fail_timeout = 30,即后面的秒单位不带) 当max_fails次失败后,暂停将请求分发到该后端服务器的时间
server 192.168.1.118:80 max_fails=3 fail_timeout=30s weight=50;
#由于这三台机器中,前两台配置高,后一台118机器配置低点,三台机器开启的nginx线上数是一样的,所以118机器设置的weight权重低。
}
#weight权限设置低,命中率就会低,这样机器压力就会减轻(若是权重不设置低点,也可以通过减少nginx线程数来减少机器压力);
server {
listen 80;
server_name www.wangshibo.com;
access_log
/usr/local/nginx/logs/www-access
.log main;
error_log
/usr/local/nginx/logs/www-error
.log;
location / {
proxy_pass http:
//LB-WWW
;
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300;
#跟后端服务器连接超时时间,发起握手等候响应时间
proxy_send_timeout 300;
#后端服务器回传时间,就是在规定时间内后端服务器必须传完所有数据
proxy_read_timeout 600;
#连接成功后等待后端服务器的响应时间,已经进入后端的排队之中等候处理
proxy_buffer_size 256k;
#代理请求缓冲区,会保存用户的头信息以供nginx进行处理
proxy_buffers 4 256k;
#同上,告诉nginx保存单个用几个buffer最大用多少空间
proxy_busy_buffers_size 256k;
#如果系统很忙时候可以申请最大的proxy_buffers
proxy_temp_file_write_size 256k;
#proxy缓存临时文件的大小
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
proxy_cache mycache;
#内存缓存源数据空间名字,对应我们前面的设定
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
}
}
|
proxy_set_header参数解释
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
|
1)proxy_redirect off
语法:proxy_redirect [ default|off|redirect replacement ]
默认值:proxy_redirect default
使用字段:http, server, location
proxy_redirect功能比较强大,其作用是对发送给客户端的URL进行修改。
如果需要修改从被代理服务器传来的应答头中的
"Location"
和
"Refresh"
字段,可以用这个指令设置。
设置为off,表示禁止所有的proxy_redirect指令.
假设被代理服务器返回Location字段为:http:
//localhost
:8000
/two/some/uri/
这个指令:
proxy_redirect http:
//localhost
:8000
/two/
http:
//frontend/one/
;
将Location字段重写为http:
//frontend/one/some/uri/
。
在代替的字段中可以不写服务器名:
proxy_redirect http:
//localhost
:8000
/two/
/;
这样就使用服务器的基本名称和端口,即使它来自非80端口。
如果使用“default”参数,将根据location和proxy_pass参数的设置来决定。
例如下列两个配置等效:
location
/one/
{
proxy_pass http:
//upstream
:port
/two/
;
proxy_redirect default;
}
location
/one/
{
proxy_pass http:
//upstream
:port
/two/
;
proxy_redirect http:
//upstream
:port
/two/
/one/
;
}
在指令中可以使用一些变量:
proxy_redirect http:
//localhost
:8000/ http:
//
$host:$server_port/;
这个指令有时可以重复:
proxy_redirect default;
proxy_redirect http:
//localhost
:8000/ /;
proxy_redirect ;
/;
参数off将在这个字段中禁止所有的proxy_redirect指令:
proxy_redirect off;
proxy_redirect default;
proxy_redirect http:
//localhost
:8000/ /;
proxy_redirect ;
/;
利用这个指令可以为被代理服务器发出的相对重定向增加主机名:
---------------------------------------------------------------------------------------------------
实例说明:
比如在做nginx反向代理时出了一点点问题,原来后端节点用的端口是8080,通过反向代理后,使用wireshark抓包发现location头域数值为http:
//192
.168.1.154:8080
/huihui/
,
如果把这个返回给客户端肯定是不可以的,看起来别扭而且还暴露了后端节点的具体信息。所以在这里用到了nginx的proxy_redirect指定修改被代理服务器返回的响应头中的location头域跟refresh头域数值。
前期配置(暴露了后端节点信息)
[root@localhost nginx]
# cat test.conf
server {
listen 80;
server_name www.wangshibo.com;
location / {
proxy_pass http:
//192
.168.1.154:8080;
proxy_redirect off;
}
}
此时我们通过curl查看结果得出
[root@localhost nginx]
# curl -I http://www.wangshibo.com/huihui
HTTP
/1
.1 301 Moved Permanently
Server: nginx
Date: Thu, 24 Dec 2015 12:02:00 GMT
Content-Type: text
/html
; charset=iso-8859-1
Connection: keep-alive
Location: http:
//192
.168.1.154:8080
/huihui/
这里location为带有后端服务器实际地址跟端口的响应头信息,这样在实际线上是不允许的。
所以这里需要通过proxy_redirect将被代理服务器的响应头中的location字段进行修改后返回给客户端
修改后的配置:
[root@localhost nginx]
# cat test.conf
server {
listen 80;
server_name www.wangshibo.com;
location / {
proxy_pass http:
//192
.168.1.154:8080;
proxy_redirect http:
//192
.168.1.154:8080
/huihui/
http:
//www
.wangshibo.com
/huihui/
;
}
server {
listen 80;
server_name www.wangshibo.com;
location / {
proxy_pass http:
//192
.168.1.154:8080;
proxy_redirect ~^http:
//192
.168.1.154:8080(.*) http:
//www
.wangshibo.com$1;
}
则curl查看返回结果
[root@localhost nginx]
# curl -I http://www.wangshibo.com/huihui
HTTP
/1
.1 301 Moved Permanently
Server: nginx
Date: Thu, 24 Dec 2015 12:08:34 GMT
Content-Type: text
/html
; charset=iso-8859-1
Connection: keep-alive
Location: http:
//www
.wangshibo.com
/huihui/
此时查看location已经变成了我们想要的结果了。 此时通过replacement 301重定向到了我们新的页面
---------------------------------------------------------------------------------------------------
2)proxy_set_header Host $host;
允许重新定义或添加字段传递给代理服务器的请求头。该值可以包含文本、变量和它们的组合。在没有定义proxy_set_header时会继承之前定义的值。
默认情况下,只有两个字段被重定义:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
实例说明:
nginx对于upstream默认使用的是基于IP的转发,如下配置:
[root@localhost nginx]
# cat test.conf
upstream backend {
server 127.0.0.1:8080;
}
upstream china {
server china.wangshibo.com;
}
server {
listen 80;
server_name www.wangshibo.com;
proxy_set_header Host $http_host;
proxy_set_header x-forwarded-
for
$remote_addr;
proxy_buffer_size 64k;
proxy_buffers 32 64k;
charset utf-8;
access_log logs
/host
.access.log main;
location =
/50x
.html {
root html;
}
location / {
proxy_pass backend ;
}
location =
/customer/straightcustomer/download
{
proxy_pass http:
//china
;
proxy_set_header Host $proxy_host;
}
}
当匹配到
/customer/straightcustomer/download
时,使用china处理,到upstream就匹配到china.wangshibo.com,这里直接转换成IP进行转发了。
假如china.wangshibo.com是在另一台nginx下配置的,ip为10.22.10.116,则$proxy_host则对应为10.22.10.116。
此时相当于设置了Host为10.22.10.116。如果想让Host是china.wangshibo.com,则进行如下设置:
proxy_set_header Host china.wangshibo.com;
如果不想改变请求头“Host”的值,可以这样来设置:
proxy_set_header Host $http_host;
但是,如果客户端请求头中没有携带这个头部,那么传递到后端服务器的请求也不含这个头部。 这种情况下,更好的方式是使用$host变量——它的值在请求包含“Host”请求头时为“Host”字段的值,在请求未携带“Host”请求头时为虚拟主机的主域名:
proxy_set_header Host $host;
此外,服务器名可以和后端服务器的端口一起传送:
proxy_set_header Host $host:$proxy_port;
如果某个请求头的值为空,那么这个请求头将不会传送给后端服务器:
proxy_set_header Accept-Encoding
""
;
3)有了下面三行配置,就可以在web的后端节点服务器端获得客户端用户的真实ip。
proxy_set_header X-Real-IP $remote_addr;
//
后端节点机器获取客户端真实ip的第一种方案
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
//
后端节点机器获取客户端真实ip的第二中方案。当然这两种方案也可以一起配置!
其中这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:
request.getAttribute(
"X-real-ip"
)
remote_addr 代表客户端的ip,但它的值不是由客户端提供的,而是服务器端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(比如nginx)就会把remote_addr设置为
你的机器ip;如果你使用了代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的ip。
x_forwarded_for 正如上面所述,当你使用了代理时,web服务器就不知道你的真实ip了。为了避免这个情况,代理服务器通常会增加一个叫做x_forwarded_for的头消息,把连接它的客户端ip(即你的上网机器的ip)
加到这个头消息里,这样就能保证网站的web服务器能获得真实ip。
使用haproxy做反向代理
通常网站为了支撑更大的访问,会增加很多web服务器,并在这些服务器前面增加一个反向代理(如haproxy)它可以把负载均衡的分布到这些服务器上。你的浏览器访问的首先是这台反向代理服务器,它再把
你的请求转发到后面的web服务器上,这就使得web服务器会把remote_addr设为这台反向代理服务器的ip,为了能让你的程序获得真实的客户端ip,就需要给haproxy增加下面的配置:
option forwardfor
它的作用就像上面说的,增加一个x_forwarded_for的头信息,把你上网机器的ip添加进去。
-----------------------------------------------------------
实际上要获得用户的真实ip,不是只有这一个方法,下面我们继续看
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
这里有个X-Forwarded-For变量,这是一个squid开发的,用于识别通过HTTP代理或负载平衡器原始IP一个连接到Web服务器的客户机地址的非rfc标准,如果有做X-Forwarded-For设置的话,
每次经过proxy转发都会有记录,格式就是client1, proxy1, proxy2,以逗号隔开各个地址,由于他是非rfc标准,所以默认是没有的,需要强制添加,在默认情况下经过proxy转发的请求,
在后端看来远程地址都是proxy端的ip 。也就是说在默认情况下我们使用request.getAttribute(
"X-Forwarded-For"
)获取不到用户的ip,如果我们想要通过这个变量获得用户的ip,
这样配置的意思是:
增加一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆盖,当然由于默认的X-Forwarded-For值是空的,所以我们总感觉X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,
实际上当你搭建两台nginx在不同的ip上,并且都使用了这段配置,那你会发现在web服务器端通过request.getAttribute(
"X-Forwarded-For"
)获得的将会是客户端ip和第一台nginx的ip。
那么$proxy_add_x_forwarded_for又是什么?
$proxy_add_x_forwarded_for变量包含客户端请求头中的
"X-Forwarded-For"
,与$remote_addr两部分,他们之间用逗号分开。
举个例子,有一个web应用,在它之前通过了两个nginx转发,www.linuxidc.com 即用户访问该web通过两台nginx。
在第一台nginx中,使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量的
"X-Forwarded-For"
部分是空的,所以只有$remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。
到了第二台nginx,使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,$remote_addr部分的值是上一台nginx的ip地址,于是通过这个赋值以后现在的X-Forwarded-For的值就变成了“用户的真实ip,
第一台nginx的ip”,这样就清楚了吧。最后我们看到还有一个$http_x_forwarded_for变量,这个变量就是X-Forwarded-For,由于之前我们说了,默认的这个X-Forwarded-For是为空的,
所以当我们直接使用proxy_set_header X-Forwarded-For $http_x_forwarded_for时会发现,web服务器端使用request.getAttribute(
"X-Forwarded-For"
)获得的值是null。如果想要通过request.getAttribute(
"X-Forwarded-For"
)获得用户ip,就必须先使用proxy_set_header
X-Forwarded-For $proxy_add_x_forwarded_for;这样就可以获得用户真实ip。
|
---------------------------------------------------------------------------------------------------------
2.url的重写
-----------------------------------------------------------------------------
介绍下url重写的格式,写在配置文件中
rewrite regex replacement [flag]
Regex:被代替的原URL路径,可以是莫须有的,不存在的,支持正则表达式
Replacement:用来实现代替的URL路径,必须真实存在的
Flag:标志位,定义URL重写后进行的操作,有4种,分别是:
a)
last:匹配重写后的URL,再一次对URL重写规则进行匹配,当使用last的需要注意的是如下:
rewrite /images/.*\.jpg /images/a.jpg last;
这样写的话,将会造成死循环。
b)
break:匹配重写URL后,终止匹配,直接使用
c)
redirect:临时重定向,返回代码302
d)
permanent:永久重定向,返回代码301
-----------------------------------------------------------------------------
下面是nginx配置文件中的配置,简单实现url的重写配置(可以在vhosts虚拟主机配置里设置)
[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
...............
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.html index.htm;
location / {
rewrite /abc http://www.huanqiu.com break; #本机站点目录下并不需要创建abc这个目录,对其的访问都重写到http://www.huanqiu.com
}
location /text {
rewrite / http://china.huanqiu.com break; #本机站点目录下不需要创建text目录,对其的访问都重写到http://china.huanqiu.com
}
}
[root@node1 src]# mkdir /var/www/html/text
注意:
nginx的rewrite重写规则后的url必须要是能在外网访问的真实url!
这一点要和nginx的反向代理区别开,proxy_pass代理后的url可以是内网访问,在内网之间代理!
3.nginx实现带健康状态检测的负载均衡
nginx要能够检测后端nginx的健康状态,需要新的模块,重新编译nginx
模块的使用:healthcheck_nginx_upstreams-master.zip
下载模块,下载到本机的/usr/loca/src目录下
下载地址:http://pan.baidu.com/s/1o8IrpbG
提取密码:vp4y
[root@node1 ~]# cd /usr/local/src
[root@node1 src]# unzip healthcheck_nginx_upstreams-master.zip
[root@node1 src]# ll healthcheck_nginx_upstreams-master
接下来切换到nginx解压目录,打补丁~
[root@node1 src]# cd nginx-1.8.0
[root@node1 nginx-1.8.0]# patch -p1 < ../healthcheck_nginx_upstreams-master
然后重新编译nginx,加上healthcheck_nginx_upstreams-master模块
[root@node1 nginx-1.8.0]# ./configure --prefix=/usr/loca/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --add-module=/usr/local/src/healthcheck_nginx_upstreams-master
[root@node1 src]# make && make install
接下来配置实现nginx带健康状态的负载均衡:
[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
..................
..................
upstream cluster {
server 192.168.1.104 weight=1;
server 192.168.1.105 weight=1;
healthcheck_enabled;
healthcheck_delay 1000;
healthcheck_timeout 1000;
healthcheck_failcount 3;
healthcheck_send "GET /.health HTTP/1.0";
#healthcheck_expected 'I_AM_ALIVE'; #从RS上收到的http body部分的响应内容,如果未设置,则表示从后端服务器收到200状态码即可,这里我们不启用
# Optional supervisord module support
#supervisord none;
#supervisord_inherit_backend_status;
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.php index.html index.htm;
proxy_pass http://cluster;
}
location /stat {
healthcheck_status;
}
}
----------------------------------------------------------------------------------------
上面参数解释:
upstream cluster //定义后方的服务器群组
Server 192.168.1.104 weight=1 //指明后方的一台服务器地址,权重设置为1;也可以IP:PORT指定端口实现端口映射
Server 192.168.1.105 weight=1 //指明后方的另一台服务器地址,权重设置为1
healthcheck_enable //开启健康探测功能
healthcheck_delay 1000 //设置健康检测的时延;即对同一台RS两次检测之间的时间间隔,单位毫秒,默认为1000
healthcheck_timeout 1000 //设置一次健康检测的超时时间
healthcheck_failcount 1 //后方某台服务器有一次检测不到即视为宕掉;即对同一台RS检测成功或失败多少次,才决定其成功或失败,并实现启用和禁用此服务
healthcheck_send "GET /.health HTTP/1.0" //使用GET方法访问后方服务器站点下的.health来进行探测;即从RS上获得用于检测健康状态的文件,默认只支持http 1.0协议
proxy_pass http://cluster //与upstream cluster相对应,在访问http://111.112.114.23时将流量转发到cluster组内机器上
location /stats //定义一个站点,用来查看后方服务器的健康状况
----------------------------------------------------------------------------------------
最后,重启nginx
[root@node1 src]# /usr/local/nginx/sbin/nginx -s reload
测试:
假如:
RS1机器上访问的结果是“welcome to 192.168.1.104”
RS2机器上访问的结果是“welcome to 192.168.1.105”
访问http://111.112.114.23,第一次出现的如果是RS1的访问结果,那么再刷一下,就会出现RS2的访问结果,这样就看出了负载均衡的效果。
可以查看后端两台Real Server服务器的健康状态:
访问http://111.112.114.23/stat即可!
关闭RS1的nginx服务,再次访问http://111.112.114.23/stat查看后端机器状态,就会发现RS1的健康状态已提示Bad,即显示后端的192.168.1.101的RS1不能正常连接。
这样就实现了负载均衡和健康探测,但依然不能满足高并发量,再次用ab进行测试:
但是,这样通过nginx代理可以满足的最大连接请求依然没有直接访问RS的大!
这个通过下面结果可知:
[root@node1 src]# ab -c 100 -n 10000 http://192.168.1.104/test.jpg
[root@node1 src]# ab -c 100 -n 10000 http://111.112.114.23/test.jpg
继续做优化!如下:
[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
proxy_cache_path /var/www/cache levels=1:2 keys_zone=mycache:20m max_size=2048m inactive=24h;
proxy_temp_path /var/www/cache/tmp;
upstream cluster {
server 192.168.1.104 weight=1;
server 192.168.1.105 weight=1;
healthcheck_enabled;
healthcheck_delay 1000;
healthcheck_timeout 1000;
healthcheck_failcount 3;
healthcheck_send "GET /.health HTTP/1.0";
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.php index.html index.htm;
proxy_set_header HOST $host;
proxy_cache STATIC;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error_timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_pass http://cluster;
}
location /stat {
healthcheck_status;
}
}
--------------------------------------------------------------
参数解释:
proxy_cache_path //设置缓存的路径和其他参数。缓存数据是保存在文件中的,缓存的键和文件名都是在代理URL上执行MD5的结果。 levels参数定义了缓存的层次结构。
proxy_set_header //允许重新定义或者添加发往后端服务器的请求头。
proxy_cache //指定用于页面缓存的共享内存。
proxy_cache_valid //为不同的响应状态码设置不同的缓存时间。
proxy_cache_use_stale //指定后端服务器出现状况时,nginx可以使用的过期缓存
---------------------------------------------------------------
接着重启nginx服务
[root@node1 src]# /usr/local/nginx/sbin/nginx -s reload
[root@node1 src]# mkdir /var/www/cache #这个前面做缓存时,已经创建了。
再次进行压力测试,可以看到通过nginx代理可以满足的最大连接请求已经达到了5000多,超过了直接访问RS的最大连接请求了!
这样负载均衡+健康探测+缓存已经完成!
[root@node1 src]# ab -c 100 -n 10000 http://111.112.114.23/test.jpg
接下来一个问题就是在启用缓存之后的访问问题,试着重新访问一下该站点http://111.112.114.23:
即第一次访问http://111.112.114.23时访问到了192.168.1.104(即RS1),显示结果是:“welcome to 192.168.1.104”,前端nginx将本次的访问结果放入本地缓存,在缓存未失效之前,访问http://111.112.114.23时实际上是nginx的本地缓存提供的访问结果,依然显示“welcome to 192.168.1.104”的页面。
可以试着多刷新几次,可以发现再怎么刷新页面内容依然是“welcome to 192.168.1.104”!
这就证明现在访问到的是nginx缓存在本地的结果!
看看缓存目录中有没有内容
[root@node1 src]# ll /var/www/cache #发现缓存目录下已经有了缓存结果;可以将这个缓存结果清除,再次刷次页面,就会是新页面了。
total 4
drwx------ 3 nginx nginx 4096 Sep 18 16:44 e
[root@node1 src]#