nginx(三) nginx配置:反向代理 负载均衡 后端健康检查 缓存
在前面《nginx详解》文章中,我们对nginx有了一个基本的认识,在《nginx编译安装 及 配置WEB服务》进行了编译安装以及配置WEB服务。下面将在前文的一些基础上,进行nginx另一个应用场景的配置:包括配置反向代理、负载均衡、后端服务器健康状态检查、缓存。
1、反向代理及负载均衡
nginx (engine x)是一个HTTP WEB服务器、反向代理服务器、邮件代理服务器和一个通用的TCP / UDP代理服务器,同时也可以提供一定的缓存服务功能。
1-1、反向代理
1、正向代理
正向代理是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
正向代理允许客户端通过它访问任意网站并且隐藏客户端自身。
典型用途:为在防火墙内的局域网客户端提供访问Internet的途径,提高安全性;可以利用缓冲特性减少网络使用率。
2、反向代理(Reverse Proxy)
反向代理是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。
典型用途:将防火墙后面的服务器提供给Internet用户访问,提高服务器的安全性。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。
1-2、负载均衡
负载均衡(Load Balance):将请求处理工作分摊到多个操作单元上进行执行,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
1-3、反向代理与负载均衡的关系
上面我们知道反向代理服务器会接受internet上客户端的连接请求,然后将请求转发给内部网络上的服务器;如果内部网络上的服务器不止一台,这时就需要反向代理服务器通过制定的负载均衡策略来转发请求到其中一台服务器上。
2、配置环境准备
2-1、模拟环境
1、各服务器主机系统:CentOS 6.4 x86_64
2、反向代理服务器:
node2: IP:192.168.18.242 (host name:node2.tjiyu.com);
service:nginx 1.10.2 提供反向代理、负载均衡和缓存等
3、后端两台realserver:
realserver1: IP:192.168.18.251 (host name:realserver1.tjiyu,com);
realserver2: IP:192.168.18.252 (host name:realserver2.tjiyu.com);
service:nginx 1.10.2 提供WEB服务
2-2、配置前所需要的准备
各主机需要做以下准备:
1、配置IP、关闭防火墙/SELINUX;
2、时间同步;
3、配置节点名称(不是必须的,最好配置上,方便操作)
在前面《heartbeat v2 haresource 配置可用集群》说到的高可用集群已有详细介绍,这里就不再给出了。
3、下载编译安装
下载、编译安装可以参考上一篇文章《nginx编译安装 及 配置WEB服务》;安装好后启动nginx,访问IP可以看到测试页面,我们把后端两台WEB服务器上的测试页面内容改一下,方便测试,如下:
4、配置nginx
置nginx的http WEB相关的内容,也即一个主要的应用场景:WEB服务器,下面我们主要配置另一个应用场景:反向代理服务器,当然也包括负载均衡、对后端服务器健康检查、缓存等相关内容。
到/etc/nginx/下可以看到nginx.conf配置文件,在《nginx详解》中我们已经详细分析说明nginx配置文件的几个配置区域块和大部分的配置选项,下面就不一一说明了,只说明一些用到的配置选项。
4-1、配置反向代理
4-1-1、配置选项说明
nginx代理基于是ngx_http_proxy_module模块的功能,该模块有很多属性配置选项,如:
proxy_connect_timeout:nginx将一个请求发送至upstream server之前等待的最大时长; proxy_cookie_domain:将upstream server通过Set-Cookie首部设定的domain属性修改为指定的值,其值可以为一个字符串、正则表达式的模式或一个引用的变量; proxy_cookie_path: 将upstream server通过Set-Cookie首部设定的path属性修改为指定的值,其值可以为一个字符串、正则表达式的模式或一个引用的变量; proxy_hide_header:设定发送给客户端的报文中需要隐藏的首部; proxy_pass:指定将请求代理至upstream server的URL路径; proxy_set_header:将发送至upsream server的报文的某首部进行重写; proxy_redirect:重写location并刷新从upstream server收到的报文的首部; proxy_send_timeout:在连接断开之前两次发送至upstream server的写操作的最大间隔时长; proxy_read_timeout:在连接断开之前两次从接收upstream server接收读操作的最大间隔时长;
此外还有如缓存配置等等,这里只讲解重要的proxy_pass和proxy_set_header,想了解更多代理指令请参考官方文档。
4-1-2、配置proxy_pass反向代理
proxy_pass配置可以分三种情况:
1、location的/uri将被替换为上游服务器上的/newuri,如下:
location /uri {
proxy_pass http://ip:port/newuri;
}
我们配置代理服务器上的location匹配"/help",将匹配URL的请求代理转发到realserver1的"/sppourt"中,过程如下:
[root@node2 nginx]# vim nginx.conf
[root@node2 nginx]# service nginx reloadlocation /help {
proxy_pass http://192.168.18.251/sppourt;
}
而后在realserver1上提供相应的测试页面,访问测试可以看到"http://192.168.18.242/help"代理到了 "http://192.168.18.251/sppourt",如下:
[root@realserver1 ~]# cd /usr/html/
[root@realserver1 html]# mkdir sppourt
[root@realserver1 html]# echo "<h1>realserver1 sppourt</h1>" >> ./sppourt/index.html
[root@realserver1 html]# cat ./sppourt/index.html
2、如果location的URI是通过模式匹配定义的,其URI将直接被传递至上游服务器,而不能为其指定转换的另一个URI。如下示例,"http://192.168.18.242/help" 代理为"htt
p://192.168.18.251/help":
location ~ ^/help {
proxy_pass http://192.168.18.251;
}
也就是说不能代理后面不能加新的URI,加了会报错,如下:
3、如果在loation中使用的URL重定向,那么nginx将使用重定向后的URI处理请求,而不再考虑上游服务器上定义的URI。如下面所示的例子中,用户访问"http://192.168.18.242/sos"重写为"http://192.168.18.242/help",传送给上游服务器的URL为"http://192.168.18.251/help",而不是"http://192.168.18.251/sppourt":
location /sos { rewrite http://192.168.18.242/help break; proxy_pass http://192.168.18.251/sppourt; }
4-1-3、配置proxy_set_header,客户端信息记录到日志
前文,4-10配置日志,我们说过这个问题:如果请求经过nginx反向代理服务器,后端web服务器无法直接获取到客户端真实的IP地址,因为$remote_addr获取到的是反向代理IP地址(192.168.18.242),如下:
[root@realserver1 ~]# vim /var/log/nginx/access.log
可以通过proxy_set_header配置反向代理服务器在转发请求的http头信息中增加"X-Forwarded-For"行信息,该信息中记录客户端IP地址,如下:
[root@node2 nginx]# vim nginx.conf
[root@node2 nginx]# service nginx reload
location /help {
proxy_pass http://192.168.18.251/sppourt; #本机"help"代理到"ttp://192.168.18.251/sppour
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#$remote_addr; #代理转发的请求头部增加"X-Forwarded-For"客户端地址
}
而后在后端realserver1服务器就配置重新定义日志格式,增加"$http_x_forwarded_for"变量信息到格式,就如原来配置文件中存在的配置,过程如下:
[root@realserver1 ~]# vim /etc/nginx/nginx.conf
[root@realserver1 html]# service nginx reload
重新访问测试,可以看到realserver1访问日志后面记录了客户端的IP信息(192.168.18.244),如下:
[root@realserver1 ~]# vim /var/log/nginx/access.log
4-2、配置负载均衡和对后端服务健康检查
4-2-1、配置选项说明
nginx负载均衡是ngx_http_upstream_module模块的功能,需要在配置文件http块上下文中定义upstream块,指定一组负载均衡的后端服务器,然后在上面据说的proxy_pass中引用,就可以反向代理时实现负载均衡了。
server选项说明:
语法:server address [parameters]; paramerters: weight:负载均衡策略权重,默认为1; max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误; fail_timeout:在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用,进行对后端服务器的健康状态检查; backup:当所有后端服务器都宕机时,可以指定代理服务器自身作为备份,对外提供维护提示页面; down:永久不可用。
upstream块里可以用多个server选项配置多个后端服务器,同时还可配置对后端服务器的健康状态检查,可以在server后面加上max_fails(proxy_next_upstream指定检查策略,默认为返回超时为失败)和fail_timeout参数实现;也可以用health_check选项来实现,health_check可以指定的参数较多,不过需要定义在location上下文中。
另外,可以指定代理服务器自身作为备份server,当所有后端服务器都宕机时,对外提供维护提示页面。
还可以指定负载均衡策略:主要有round_robin(加权轮询,默认)、hash、ip_hash、least_conn(最少连接)和least_time(最少响应时间,商业版本),策略定义在upstream上下文即可;
4-2-2、配置操作
先在配置一个名为webserver的upstreat块,里面包含三个server:realserver1、realserver2和代理服务器自身,配置对后端服务器的健康状态检查、负载均衡策略;然后在location中的pxory_pass中引用该webserver组,配置如下:
upstream webserver { #定义名为webserver的负载均衡组,在下面proxy_pass引用
#ip_hash; #ip_hash负载均衡策略,注意,当下面定义代理服务器为backu时,当后端服务器重新上线时,不能进行>正常转发
least_conn; #最少连接负载均衡策略
#least_time last_byte; #最少响应时间策略,商业版本
server 192.168.18.251 weight=2 max_fails=2 fail_timeout=2; #realserver1 权重2/两次检测失败,不向其转发/检
查超时两秒为失败
server 192.168.18.252 weight=1 max_fails=2 fail_timeout=2; #realserver2
server 127.0.0.1:8080 weight=1 backup; #指定代理服务器自身作为备份server,当所有后端服务器都宕机时,对外>提供维护提示页面
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://webserver; #引用上面定义的upstream负载均衡组
}
……
然后再配置一个提供维护提示页面的虚拟主机,并创建提示页面,操作配置如下:
server { #定义虚拟主机,当所有后端服务器都宕机时,使得代理服务器自身可以对外提供维护提示页面
listen 8080;
server_name localhost;
root /data/web/errorpage;
index index.html;
}
[root@node2 ~]# mkdir -pv /data/web/errorpage
[root@node2 ~]# echo "<h1>errorpage</h1>" >> /data/web/errorpage/index.html
[root@node2 ~]# cat !$
4-2-3、测试
访问代理服务器IP,可以看到请求被均衡转发到两台realserver上,如下:
两台realserver上的WEB服务都停止时,可以看到代理服务器自身提供维护页面,如下:
两台realserver又上线正常后,可以看到代理服务器又能正常均衡转发,如下:
统计访问连接数,可以用以下命令:
[root@node2 ~]# netstat -an | grep :80 | wc -l
4-3、配置缓存
Nginx常用的缓存可以分为四类:
1、pxory_cache:代理缓存,作为代理服务器时,缓存后端服务器响应内容等;
2、open_log_cache:日志缓存;
3、open_file_cache:文件缓存,作为WEB服务器时需要响应文件给客户端,这可以提高发生,相关指令前面《nginx详解》有介绍;
4、fastcgi_cache:后端php动态响应内容缓存,可能影响响应内容更新。
缓存数据分为两部分(键:数据):
1、存储键和缓存对象元数据,存放在共享内存中;
2、存储缓存数据,存放在磁盘空间中;
4-3-1、代理缓存配置选项说明
我们这里只介绍代理缓存pxory_cache,这也是ngx_http_proxy_module模块提供的功能,这里配置选项较多,下面主要介绍有几个基本的选项:proxy_cache_path、proxy_cache和proxy_cache_valid。
1、proxy_cache_path
proxy_cache_path定义一个完整的缓存空间,指定缓存数据的磁盘路径、键(元数据)存放的内存空间以及一些其他参数,如缓存删除策略。注意,该选项只能定义在http块上下文中。
如,proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m max_size=1G inactive=10; 缓存数据存储在/data/nginx/cache目录中; levels:配置在该目录下再分两层目录,一层1个随机字符作为名称,二层2个随机字符作为名称,levels最多三层,每层最多两个字符,这是为了加快访问文件的速度;最后使用代理url的哈希值作为关键字与文件名,一个缓存数据如下:/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c; keys_zone:指定键(元数据)存放的内存空间,指定名称为one,这个名称后面proxy_cache需要引用;而10m就是内存空间的大小; max_size:指定最大缓存数据磁盘空间的大小; inactive:在inactive指定的时间内,未被访问的缓存数据将从缓存中删除。
2、proxy_cache
proxy_cache用来引用上面proxy_cache_path定义的缓存空间,现时打开缓存功能,如下:
proxy_cache one; #引用上面定义上的缓存空间,同一缓存空间可以在几个地方使用
3、proxy_cache_valid
proxy_cache_valid设置不同响应代码的缓存时间,如:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
对代码200和302的响应设置10分钟的缓存,对代码404的响应设置为1分钟。
4-3-2、配置代理缓存
先配置pxory_cache_path,再配置pxory_cache引用、打开缓存空间,接着配置两个proxy_cache_valid;为方便调试测试,我们可以通过add_header给请求响应增加一个头部信息,表示从服务器上返回的cache状态怎么样(有没有命中),主要配置如下:
#定义一个完整的缓存空间; 缓存数据存储在/data/nginx/cache目录中/配置在该目录下再分两层目录/键(元数据)存放的>内存空间,名称为one(proxy_cache引用),10m内存空间大小/最大缓存数据磁盘空间的大小/10m未被访问的缓存数据将从缓存中删除
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m max_size=1G inactive=10m;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
add_header X-Cache "$upstream_cache_status form $server_addr"; #给请求响应增加一个头部信息,表示从服务器上返回的cache状态怎么样(有没有命中)
location / {
proxy_pass http://webserver; #引用上面定义的upstream负载均衡组
proxy_cache one; #引用上面定义上的缓存空间,同一缓存空间可以在几个地方使用
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m; #对代码200和302的响应设置10分钟的缓存,对代码404的响应设置为1分钟:
}
……
然后,创建缓存目录,重新加载,如下:
[root@node2 ~]# mkdir -pv /data/nginx/cache
[root@node2 ~]# service nginx reload
访问测试,第一次可以看到响应头"X-Cache:MISS from 192.168.18.242"表示没有命中缓存;第二次"…HIT…"表示命中缓存;再查看缓存目录,看到缓存数据,如下::
到这里,我们完成了nginx在代理应用方面的配置:包括配置反向代理、负载均衡、后端服务器健康状态检查、缓存,后面有时间将会在本文件的基础上进行keepalived + nginx代理服务器的高可用集群配置,以及nginx+tomcat的动静分离配置……
【参考资料】
1、nginx官网文档:http://nginx.org/en/docs/
2、nginx详解:
3、nginx编译安装 及 配置WEB服务:
4、Nginx 反向代理、负载均衡、页面缓存:http://freeloda.blog.51cto.com/2033581/1288553