反向代理
使用proxy_pass指令,在ngx_http_proxy_module模块下,其中有具体用法和相关文档
首先给出小结:
情形A和情形B进行对比,可以知道proxy_pass后带一个URI,可以是斜杠(/)也可以是其他uri,对后端request_uri变量的影响。 情形D说明,当location为正则表达式时,proxy_pass不能包含URI部分。 情形E通过变量($request_uri, 也可以是其他变量),对后端的request_uri进行改写。 情形F和情形G通过rewrite配合break标志,对url进行改写,并改写后端的request_uri。需要注意,proxy_pass地址的URI部分在情形G中无效,不管如何设置,都会被忽略。
server {
listen 80;
server_name www.test.com;
# 情形A
# 访问 http://www.test.com/testa/aaaa
# 后端的request_uri为: /testa/aaaa
location ^~ /testa/ {
proxy_pass http://127.0.0.1:8801;
}
# 情形B
# 访问 http://www.test.com/testb/bbbb
# 后端的request_uri为: /bbbb
location ^~ /testb/ {
proxy_pass http://127.0.0.1:8801/;
}
# 情形C
# 下面这段location是正确的
location ~ /testc {
proxy_pass http://127.0.0.1:8801;
}
# 情形D
# 下面这段location是错误的
#
# nginx -t 时,会报如下错误:
#
# nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular
# expression, or inside named location, or inside "if" statement, or inside
# "limit_except" block in /opt/app/nginx/conf/vhost/test.conf:17
#
# 当location为正则表达式时,proxy_pass 不能包含URI部分。本例中包含了"/"
location ~ /testd {
proxy_pass http://127.0.0.1:8801/; # 记住,location为正则表达式时,不能这样写!!!
}
# 情形E
# 访问 http://www.test.com/ccc/bbbb
# 后端的request_uri为: /aaa/ccc/bbbb
location /ccc/ {
proxy_pass http://127.0.0.1:8801/aaa$request_uri;
}
# 情形F
# 访问 http://www.test.com/namea/ddd
# 后端的request_uri为: /yongfu?namea=ddd
location /namea/ {
rewrite /namea/([^/]+) /yongfu?namea=$1 break;
proxy_pass http://127.0.0.1:8801;
}
# 情形G
# 访问 http://www.test.com/nameb/eee
# 后端的request_uri为: /yongfu?nameb=eee
location /nameb/ {
rewrite /nameb/([^/]+) /yongfu?nameb=$1 break;
proxy_pass http://127.0.0.1:8801/;
}
access_log /data/logs/www/www.test.com.log;
}
server {
listen 8801;
server_name www.test.com;
root /data/www/test;
index index.php index.html;
rewrite ^(.*)$ /test.php?u=$1 last;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
access_log /data/logs/www/www.test.com.8801.log;
}负载均衡
相关的指令在ngx_http_upstream_module中,详情请查看文档
其中定义upstream的语句需要写到http模块下
示例一
http {
# 不设置负载均衡策略默认为轮训,每个server的weight为1
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}该示例将所有到80端口的请求全部转发到backend中去
示例二
http {
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com weight=3;
server backend3.example.com weight=2;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}以上将设置权重,将请求按照5:3:1的比例来进行分配
示例三
http {
upstream backend {
server backend1.example.com fail_timeout=30s max_fails=3 ;
server backend2.example.com backup;
server backend3.example.com backup;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}使用了fail_timeout参数为后端服务器配置故障超时时间,使用max_fails设置最大失败次数为3。如果某个后端服务器在出现3次故障,Nginx将会将其标记为不可用,并将不再向其转发请求,过了30秒后再向其转发请求。此外,还使用了backup参数来指定一个备用服务器,当所有主服务器都不可用时,Nginx会将请求转发到备用服务器。这种方式可以提高服务的可用性,防止因为某个服务器故障而导致整个服务不可用的情况发生。
示例四
http {
upstream backend {
hash $request_uri;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}在这个例子中,upstream指令使用了hash方法,并使用**$request_uri**变量作为哈希键值。当客户端发送请求时,Nginx会根据请求的URI计算哈希值,并将该请求转发到哈希值对应的后端服务器上。这样做可以确保相同的请求总是被转发到同一个后端服务器上,从而实现会话一致性。
需要注意的是,使用hash方法进行负载均衡可能会导致负载不均衡的情况。例如,如果某个URI的请求量非常大,那么对应的后端服务器可能会承担更大的负载。因此,在使用hash方法进行负载均衡时,需要仔细选择哈希键值,以避免出现负载不均衡的情况。