配置Nginx作为反向代理服务器
一、nginx作为反向代理的工作模型:
1、nginx作为反向代理的工作模型
nginx工作在应用层,其能理解并可以提取出http请求报文中的首部信息中的请求方法、url、http协议版本等信息。
nginx反向服务器接收到请求报文之后,会启动一个请求连接,把用户的请求重新封装为一个请求报文,由nginx反向服务器作为客户端向Real Server进行请求。
此时,nginx反向代理服务器中封装的首部信息可能与接受到的客户端的首部信息不完全一致,这取决于其与RS(Real Serve)协商的结果。
nginx作为反向代理其功能类似于DNAT所实现的功能,能够实现隐藏真实服务器的目的。
2、nginx也具有缓存功能
nginx作为反向代理服务器也具有缓存功能,但其首先是反向代理服务器,之后才是缓存服务器。
反带和缓存是两个不同的功能。
透传式代理才具有缓存功能:
来自于客户端的请求,若在Nginx Server上没有相应的内容,Nginx Server要负责向Real Server发起请求获取内容。对于Client来说,Real Server是不可见的。
旁路式缓存/旁挂式缓存:
Client直接向缓存服务器请求,缓存服务器没有相应的内容,Client要想Real Server发起请求,由Real Server响应。
Nginx作为http服务器的缓存时,只对get、head等读请求方法作缓存查询。
Nginx查找缓存时,若没有命中缓存,会产生额外的开销,因此,提升缓存命中率是必要的。根据LRU(最近最少算法)清理缓存。缓存有效期,确保缓存的内容与原服务器的内容一致,有效期到达之后,缓存服务器发送条件式请求,询问原服务器资源是否发生改变,若没有发生改变,则不会清理。
X-Forwarded-for用来解决在RS上无法分析到真实客户端的请求IP的问题,反带服务器在接受到客户端的请求时,会检查请求报文中的首部信息,若其不存在X-Forwarded-for信息,则其将Client的真实IP信息记录于其中,若已存在,则不再另行封装,之后,再将报文发给RS,在RS上即可查看到Client的IP信息。
二、Nginx作为反向代理的实现
通过ngx_http_proxy_module模块来实现反向代理的功能
1、proxy_pass URL;指定代理至后端服务器的URL
Context位置:location, if in location, limit_except
注意:
1)proxy_pass后面的路径不带uri时,其会将location的uri传递给后端主机;
server {
…
server_name HOSTNAME;
location /uri/ {
proxy http://hos[:port];
}
…
}
http://HOSTNAME/uri –> http://host/uri
2)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/
3)如果location定义其uri时使用了正则表达式的模式,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后;
server {
…
server_name HOSTNAME;
location ~|~* /uri/ {
proxy http://host;
}
…
}
http://HOSTNAME/uri/ –> http://host/uri/;
配置示例1:
实验环境:
nginx proxy server:centos7 192.168.154.130
webserver1:centos6.8 192.168.154.128
webserver2:centos6.8 192.168.154.129
目的:1)实现访问192.168.154.130其页面为192.168.154.129提供的页面
2)实现访问192.168.154.130/wordpress其页面为192.168.154.128提供的页面
3)实现访问192.168.154.130/wordpress其页面为192.168.154.128/wordpress提供的页面。注意第2和第三配置实现的区别
192.168.154.128提供的页面内容为:
192.168.154.128/wordpress提供的页面内容为:
192.168.154.129提供的页面内容为:
配置步骤
1)
a)、在nginx server上安装nginx,过程略
b)、配置nginx.conf文件,在对应的server上下文中配置:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
proxy_pass http://192.168.154.129;
index index.html index.htm;
}
注意:若root与proxy_pass配置同时出现,则proxy_pass生效。也可以注释掉root
c)测试配置文件是否有误
nginx -t
d)启动nginx或重新加载配置文件
nginx 或 nginx -s reload
e)在webserver上安装httpd,配置测试站点,启动httpd服务。
f)通过访问nginx proxy server,测试反带配置是否成功
2)当proxy_pass http://192.168.154.128;后带uri时
其会将location后的/wordpress/替换为proxy_pass http://192.168.154.128后的uri,即传递给后端RealServer的url为http://192.168.154.128/,其请求获取的资源为192.168.154.128/提供的页面内容
3)当proxy_pass http://192.168.154.128;后不带uri时
其会将location后的/wordpress/补在proxy_pass http://192.168.154.128后,即传递给后端RealServer的url为http://192.168.154.128/wordpress。其请求获取的资源为192.168.154.128/wordpress提供的页面内容
配置示例2:
实现访问任何图片资源,其请求的内容都是由192.168.154.128提供的图片资源,配置如下:
location ~* \.(jpg|img|jpeg|png)$ {
proxy_pass http://192.168.154.128;
}
要能成功访问,请求的资源必选已经存在于192.168.154.128服务器上。
测试访问:http://192.168.154.130/1.jpg
测试访问:http://192.168.154.130/imgs/test2.jpg
配置示例2:
实现将php页面的访问请求都提交给192.168.154.128
location ~* \.php$ {
proxy_pass http://192.168.154.128;
}
在192.168.154.128上要安装配置好php,之后测试
三、如何解决Real Server后端记录的日志IP为反带服务器的IP,而不是真正的Client的IP。
proxy_set_header field value;
设定发往后端主机的请求报文的请求首部的值;
Context位置:http, server, location
1、Client与Real Server之间的请求只经过一次反带。
直接在发往后端主机的请求报文首部中设定Client的IP。
proxy_set_header X-Real-IP $remote_addr;
2、Client与Real Server之间的请求经过多级反带。
此时,如果直接直接在发往后端主机的请求报文首部中设定Client的IP。
在经过多级代理之后,其记录的IP为最后一级代理服务器的上一级代理的IP,并不是真正的Client的IP。真正的Client IP被记录在$proxy_add_x_forwarded_for变量中,只需向后端Real Server传递此变量即可。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
配置步骤:
1)编辑nginx.conf文件,在需要记录日志的相应上下文加上
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2)在后端Real Server上配置
变价httpd.conf配置文件,修改LogFormat配置,将反带服务器传递的参数替代%h
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
在后端Real Server上追踪httpd访问日志,
四、定义和启用nginx的缓存机制
1、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];
2、proxy_cache zone | off;
指明要调用的缓存,或关闭缓存机制;
Context位置:http, server, location
3、 proxy_cache_key string;
缓存中用于“键”的内容;
默认值:proxy_cache_key $scheme$proxy_host$request_uri;
注意:1)当缓存服务器要同时支持http及https,使用$scheme会造成http和https不能共享缓存。
2)当后端RS不止一台服务器时,使用$proxy_host,被调度后也不能共享缓存
因此,可以显示指定仅使用$request_uri为缓存中的"键"。
4、proxy_cache_valid [code …] time;
定义对特定响应码的响应内容的缓存时长;
定义在需要调用缓存功能的配置段,例如server{…}或location{…};
配置示例:
缓存图片资源。
1)定义缓存
proxy_cache_path只能定义在http{…}中;
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=pxycache:20m max_size=1g;
2)调用缓存
3)创建缓存目录,mkdir -pv /var/cache/nginx/proxy_cache
4)测试配置是否有误
5)重载配置
之后,请求http://192.168.154.130/1.jpg,查看缓存是否命中。
缓存相关的优化配置:
5、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 …;
当代理服务器与后端主机通信出现故障时,在哪种情况下可以使用缓存中的缓存项响应给客户端。此缓存项内容可能过期。
error、timeout、invalid_header…表示通信故障描述,即当代理服务器与后端RS通信故障原因为指定的短语时,使用缓存内容响应给客户端。
off表示不使用过期内容响应给客户端
6、proxy_connect_timeout time
定义代理与后端RS的连接超时时长,默认为60秒,最大不能超过75秒。
7、proxy_cache_methods GET | HEAD | POST …;
定义为哪些请求方法是用缓存。建议仅对GET、HEAD方法是用缓存,默认也为GET、HEAD方法。
五、对后端服务器响应报文的header的处理
1、proxy_hide_header field
指明要隐藏的后端服务器响应报文的header,默认情况下,不会传递“Date”, “Server”, “X-Pad”, and “X-Accel-…”header的信息。此定义能够避免后端服务器信息被泄露。
2、使用ngx_http_headers_module模块,可以实现由代理服务器响应给客户端的响应报文中添加自定义首部,或,修改指定首部的值。
2.1 、add_header name value [always];添加自定义首部;
Context位置:http, server, location, if in location
add_header X-Via $server_addr;告知客户端其请求是由谁代理
add_header X-Accel $server_name;告知客户端其请求由谁给予加速
2.2、expires [modified] time;用于定义Expire的值,其应用场景为,假若在反带服务器上,设定缓存在1小时之后过期,但经过判定,该内容长期不会改变,此时,修改expires的值
expires epoch | max | off; 用于修改Cache-Control首部的值;
Context位置:http, server, location, if in location
示例:在nginx上增加X-via、X-Accel响应头部
之后,测试配置是否有误,重新加载配置。
在客户端通过浏览器查看器响应头部,可以查看到增加的头部信息
六、Nginx反带实现负载均衡
通过ngx_http_upstream_module模块来定义后端服务器组,在后端服务器组中能够实现负载均衡调度。
Nginx作为反带时支持对后端服务器的监控状态做检测,当其检测到无法与某后端服务器建立连接时,其不会再将请求调度至该服务器。
在使用负载均衡功能时,Nginx反带服务器和各Real Server之间的时间必须要同步。
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;
max_fails=number 失败尝试最大次数;超出此处指定的次数时,server将被标记为不可用;
fail_timeout=time 设置将服务器标记为不可用状态的超时时长,默认为10秒;
max_conns 当前的服务器的最大并发连接数;
backup将服务器标记为“备用”,即所有服务器均不可用时此服务器才启用;
down 将服务器标记为“不可用”;
配置示例:
实验环境:
nginx proxy server:centos7 192.168.154.130
webserver1:centos6.8 192.168.154.128
webserver2:centos6.8 192.168.154.129
实验1:实现将对nginx server的请求负载均衡调度至webserver1、webserver2,为了以示区别,webserver1、webserver2提供不同的页面内容。
webserver1提供的页面内容为:
webserver2提供的页面内容为:
配置步骤
1)在nginx.conf中定义名为webcluster的upstream
注意,server不能指定协议,在引用时指定即可
2)在要实现负载的server上下文或location上下文中定义proxy_pass,引用定义好的upstream即可。
3)测试配置是否有误,之后重载配置
4)测试。
默认情况下,负载均衡使用的算法为RR(Round Robin)算法。
实验2:根据服务器负载能力,将对nginx server的请求按负载调度至webserver1、webserver2,假设webserver1负载能力为2,webserver2负载能力为1。
配置如下:
1)在upstream中的server后指定权重即可。
默认情况下,权重的值为1,可不用特别指定。
2)测试配置是否有误,之后重载配置
3)测试。
3、least_conn; 我们知道nginx进行调度时,期默认算法为轮询算法,轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同。这有个前提,就是每个请求所占用的后端时间要差不多,如果有些请求占用的时间很长,会导致其所在的后端负载较高。在这种场景下,把请求转发给连接数较少的后端,能够达到更好的负载均衡效果,这就是least_conn算法。
least_conn首先遍历后端集群,比较每个后端的conns/weight,选取该值最小的后端。如果有多个后端的conns/weight值同为最小的,那么对它们采用加权轮询算法。。
4、 ip_hash; 源地址hash调度方法;基于Client的IP做调度。将来至于同一个IP地址的请求分发给同一个后端服务器。
配置示例:
检查并重载配置
测试
5、hash key [consistent] ; 基于指定的key的hash表来实现对请求的调度,此处的key可以直接文本、变量或二者的组合;
作用:将请求分类,同一类请求将发往同一个upstream server;
consistent,使用一致性hash算法,其意义在于,当某台RS出现故障时,能够降低影响到的掉读请求的范围。
示例:
hash $request_uri consistent;同一个uri请求将会被分发至相同的RS上。
hash $remote_addr; 同一个IP地址的请求将会被分发至相同的RS上,类似于ip_hash。
hash $cookie_name;来至于同一个浏览器的请求将会 被分发至相同的RS上。
6、keepalive connections; 为每个worker进程保留的空闲的长连接数量;
在nginx上没有启用缓存时,来至于客户端的请求都会被调度至后端服务器,当请求数较大时,如果使用短链接,会消耗掉大量的Nginx反带服务器上的端口,为了避免出现此情况,在Nginx与RS连接时,可以使用长连接。
七、使用Nginx反带、分发tcp或udp协议
基于ngx_stream_core_module来实现此功能。此时Nginx工作与传输层。
1、stream { … } 定义stream相关的服务;
Context位置:main
stram上下文与http上下文为平级关系,在stream上下文中,也可以使用http中的方法来定义。
stream {
upstream name {
server ip[:port];
server ip[:port];
…
}
server {
listen ip[:port]; 定义通过哪个ip及port来接受请求
proxy_pass sshsrvs; 此处的proxy_pass不可指定协议,只需将其请求调度至后端服务器即可。
}
}
2、listen
listen address:port [ssl] [udp] [proxy_protocol] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
配置示例:
在webserver1、webserver2分别配置mysql服务,以mysqlserver1、mysqlserver2加以区别。通过192.168.154.130:33106来实现对后端mysql服务请求的负载均衡调度。
为了能够明晰测试,在mysqlserver1、mysqlserver2分别创建名为server1、server2的database,且授权同一个用户能够在远程访问。此配置不再赘述。
配置stream步骤:
1)编辑nginx.conf文件,增加一下内容
注意其上下文位置需与http同级。
2)测试配置是否有误,之后重载配置
3)查看33106端口是否监听
4)在远端主机上进行测试
for i in {1..10};do mysql -ucluster -h192.168.154.130 -P 33106 -pcluster -e "show databases;"; done
原创文章,作者:M20-1钟明波,如若转载,请注明出处:http://www.178linux.com/55565