简而言之,Nginx与其他反向代理服务器(如Squid)相比,特点是:
Nginx不会直接将客户端的HTTP请求直接发给上游服务器(Tomcat),而是先把用户的请求(包括HTTP包体)完整的接收到Nginx所在服务器的磁盘或者内存中,然后再向上游服务器发起连接,转发请求。
缺点: 延长了HTTP请求的处理时间,且增加了Nginx本地的用于缓存的内存和磁盘空间;
优点: 降低了上游服务器(Tomcat、Apache)的负载(并发压力),尽量把压力放在Nginx服务器上。
原因:
客户端与反向代理服务器之间的网络连接是公网,反向代理服务器与上游服务器之间的连接是内网(局域网)或者专线连接。
如果刚收到HTTP请求就立即与上游服务器建立连接,假如客户端上传1G的文件,则在此期间上游服务器要一直保持连接,这对上游服务器的并发处理能力提出了挑战。
而Nginx接收到完整的客户端文件后才与上游服务器建立连接,且内网的转发执行很快。
但是,当上游服务器一旦开始回复HTTP响应时,Nginx反向代理服务器会立刻把应答包转发给客户端。
TIPS:
反向代理服务器(reverse proxy)必须能够处理大量的并发请求(高并发高负载能力)。
“负载均衡”指的是代理服务器向上游服务器集群(upstream)转发请求时,要选择一种转发策略,尽量把请求平均的分布到每一台上游服务器上。
Nginx的负载均衡策略分为 5 种:
(1)RR(默认)(顺序)
(2)权重
(3)ip_hash(第三方)
(4)fair(第三方)
(5)url_hash(第三方)
http {
upstream backend {
server www.baidu.com;
server 192.254.1.16; # 如果不写端口号,默认80
server 192.254.3.16:9000;
}
server {
location / {
proxy_pass http://backend;
}
}
}
upstream块里面定义的是上游服务器集群,块中的server配置项指定一台上游服务器的名字,可以是IP地址端口、域名、Unix句柄。
“proxy_pass”是代理通行证的意思。
# (1)server后面接weight=number,设置这台上游服务器的权重,默认为1
http {
upstream backend {
server 192.254.1.16 weight=2;
server 192.254.3.16 weight=1;
}
}
# 注: weight=2; 中间不能有空格,否则会报错
# (2)
http {
upstream backend {
server 192.254.1.16:9000 max_fails=3 fail_timeout=30s;
}
}
# 在30秒的时间内向这台上游服务器转发3次都失败,就认为这台服务器暂时不可用,默认max_fails=1,如果为0表示不检查
这种负载均衡的策略很重要:当有大量用户同时访问服务器时,用户初始接入的那台上游服务器(Tomcat)会缓存一些客户信息,如果之后同一个用户的HTTP请求被Nginx转发到集群中的任意一台上游服务器上去,那么每一个上游服务器都要缓存同一份用户信息,这会造成服务器的内存资源浪费且管理这些缓存信息会非常困难。
在这种场景下,我们希望 来自同一个用户的HTTP请求始终落到固定的某一台上游服务器上
, 这就是 ip_hash 的作用。
ip_hash 的工作原理:
首先根据客户端的IP地址计算出一个key,将key按照upstream集群里的上游服务器数量进行取模,然后以取模后的结果把请求转发到相应的上游服务器中。这样就确保了同一个客户端的请求只会转发到指定的上游服务器上。
注意:
(1)ip_hash不能与weight权重配置同时使用,会引起分配冲突;
(2)upstream配置块中如果有一台服务器不可用或不再使用,不能在upstream块中直接将其删除,而是要用 down
参数标识,以保证key取模后的结果不变,确保转发策略的一贯性,例如:
http {
upstream backend {
ip_hash; # 在普通的顺序upstream中加入"ip_hash"关键字即可
server 192.254.1.16:9000;
server 192.254.3.19:9001;
server 192.254.7.16:9002 down;
}
}
按上游服务器的响应时间来分配请求
,响应时间短的优先分配。
upstream backend {
fair; # 在upstream第一行标明fair即可
server 127.0.0.1:9000;
server 127.0.0.1:9001;
}
按访问服务器URL的Hash结果来分配请求到上游服务器,使每个URL定向到同一个上游服务器上去,上游服务器为缓存时比较有效。
与ip_hash的区别:
ip_hash是按照客户端的IP地址计算Hash结果,使得每个客户端固定接入到一台上游服务器上;url_hash按照URL计算Hash结果,使访问同一个URL资源的不同客户端接入到同一台上游服务器上,这种方法当上游服务器为提供固定的资源的缓存时比较有效。
url_hash方法下同样不能在server后面接weight等关键字。
upstream backend {
hash $request_uri;
hash_method crc32;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
反向代理的基本配置项有以下几个:
(1) proxy_pass [URL];
(2) proxy_method [Method];
(3) proxy_hide_header
(4) proxy_pass_header
(5) proxy_pass_request_body
(6) proxy_pass_request_headers
(7) proxy_redirect
(8) proxy_next_upstream
proxy_pass可以理解为“代理通行证”,此配置项将当前请求反向代理到URL参数指定的上游服务器上去,URL可以是IP地址端口号、主机名等。
例如下例中表示proxy_pass的URL是 http://backend
http {
upstream backend {
server 192.254.1.16;
server 192.254.3.16;
}
server {
listen 9000;
server_name 10.4.211.156;
location / {
proxy_pass http://backend;
}
}
}
注:upstream块中的上游服务器必须已经开启,否则转发到此服务器上最后会返回“502 Bad Gateway”
参考内容:
《深入理解Nginx - - 模块开发与架构解析》