URL转发应用场景
根据HTTP的URL转发的场景,被称之为七层转发(应用层转发),然而LVS的负载均衡一般用于TCP的转发,也就被称之为4层转发。
利用Nginx的七层转发,可以实现动静分离,移动、PC端页面区分,交给不同的后端服务器处理,让用户得到更佳的访问体验。
通过$http_user_agent
获取,根据该变量获取到的用户客户端信息,再决定交给哪一个后端服务器去处理。
根据日志access.log扑捉到的信息,检测到客户端是来自哪个浏览器、手机、ipad等;
curl命令客户端
[root@lb01 ~]# curl www.junwu.com/static/index.html 这里是分布式静态服务器static 10.0.0.30 - - [28/Jun/2023:00:48:06 -0400] "GET /static/index.html HTTP/1.1" 200 40 "-" "curl/7.29.0"
Edge浏览器
10.0.0.1 - - [28/Jun/2023:00:49:19 -0400] "GET /upload/ HTTP/1.1" 200 25 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58"
Nginx根据客户端信息转发配置
利用shell语句进行逻辑判断
upstream static_pools { server 10.0.0.40; } upstream upload_pools { server 10.0.0.50; } upstream default_pools { server 10.0.0.60; } server { listen 80; server_name www.junwu.com; #修改如下代码,测试直接return状态码,更直观看见区别 location / { if ($http_user_agent ~* "Chrome") { # proxy_pass http://static/pools; return 401; } if ($http_user_agent ~* "curl") { return 402; } if ($http_user_agent ~* "Safari") { # proxy_pass http://upload_pools; return 403; } proxy_pass http://default_pools; }
[root@lb01 ~]# nginx -s reload
查看实际转发效果
上述代码含义
- 如果客户端的User-Agent中包含"Chrome",则请求会返回状态码401
- 如果客户端的User-Agent中包含"curl",则请求会返回状态码402
- 如果客户端的User-Agent中包含"Safari",则请求会返回状态码403
- 否则,请求会被转发到http://default_pools
10.0.0.1 - - [29/Jun/2023:10:27:28 -0400] "GET / HTTP/1.1" 401 581 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.0.0.30 - - [29/Jun/2023:10:28:45 -0400] "GET / HTTP/1.1" 402 167 "-" "curl/7.29.0" [root@lb01 ~]# curl www.junwu.com <html> <head><title>402 Payment Required</title></head> <body> <center><h1>402 Payment Required</h1></center> <hr><center>nginx/1.25.1</center> </body> </html>
通过文件扩展名转发
【方法一:通过location匹配】
1.通过检测用户发请求的文件后缀名来转发
location ~ .*.(gif|jpgjpeg|png|bmp|swf|css|js)$ { # proxy_pass http://static_pools; # include proxy.conf; return 501; } # 重启nginx -s reload
【方法二:通过shell语句判断】
location / { if ($http_user_agent ~* "Chrome") { # proxy_pass http://static/pools; return 401; } if ($http_user_agent ~* "curl") { return 402; } if ($http_user_agent ~* "Safari") { # proxy_pass http://upload_pools; return 403; } #添加如下代码 if ($request_uri ~* ".*\.(php|php5)$") { proxy_pass http://static/pools; } if ($request_uri ~* ".*\.(jsp|jsp*|do|do*") { proxy_pass http://upload_pools; }
重启nginx服务会提示报错
[root@lb01 ~]# nginx -s reload 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/nginx-1.25.1/conf/nginx.conf:99
这个错误提示是因为在 `location` 块中使用了带有 URI 部分的 `proxy_pass` 指令,而根据 Nginx 的规则,这种语法是不允许的。
在 Nginx 中,当你使用 `proxy_pass` 指令时,URI 部分应该是在指令中指定的目标后端服务器的地址中设置的,而不是在 `location` 块中。
要解决这个错误,你可以将 `proxy_pass` 指令移到 `server` 或 `location` 块的外部,或者将其设置为不带 URI 部分的形式。例如,你可以将 `proxy_pass` 指令修改为以下形式:
```
proxy_pass http://default_pools/;
```
注意最后的斜杠 `/`,它将会在转发请求时保留原始请求的 URI 部分。
确保修改后的配置符合 Nginx 的语法规则,并重新加载 Nginx 配置文件以使更改生效。
这两行在 if
块中使用了带有 URI 部分的 proxy_pass
指令,导致出现错误。为了修复这个问题,你可以将这两行修改为不带 URI 部分的形式,如下所示:
rewrite ^ http://static/pools$uri last; rewrite ^ http://upload_pools$uri last;
上述修改使用了 rewrite
指令,它将请求重写为指定的地址,并将 URI 部分保留在重定向后的请求中。
修改后的代码如下:
location / { if ($http_user_agent ~* "Chrome") { # proxy_pass http://static/pools; return 401; } if ($http_user_agent ~* "curl") { return 402; } if ($http_user_agent ~* "Safari") { # proxy_pass http://upload_pools; return 403; } if ($request_uri ~* ".*\.(php|php5)$") { rewrite ^ http://static/pools$uri last; } if ($request_uri ~* ".*\.(jsp|jsp*|do|do*)$") { rewrite ^ http://upload_pools$uri last; } proxy_pass http://default_pools;
标签:http,URL,pass,Nginx,proxy,转发,pools,return From: https://www.cnblogs.com/junwured/p/17510361.html