目录
-
- 一、知识回顾
- [二、proxy_pass 结尾带 / 和不带 / 的区别](#二、proxy_pass 结尾带 / 和不带 / 的区别)
-
- [2.1 场景假设](#2.1 场景假设)
- [2.2 实战验证](#2.2 实战验证)
- [2.3 结论](#2.3 结论)
一、知识回顾
之前使用过 Nginx 的小伙伴或许都了解,Nginx
是一款用于请求转发的高性能中间件,它的配置文件 conf/nginx.conf
中可以通过 location
去定义一些转发规则,nginx.conf 内容大概如下所示:
如果请求成功匹配到 location 的规则,不同的请求类型对应的转发配置不同:
- 静态资源: 使用 alias、root 关键字。
- API接口: 使用 proxy_pass 关键字。
那么 问题来了! Nginx 对 API接口进行转发时,下面这两种 proxy_pass
的配置方式对于请求的转发有没有区别呢?
proxy_pass http://localhost:8080/;
proxy_pass http://localhost:8080;
作为小白的我是觉得没有区别的,但 其实不然,下面我们就实战检验一下。
二、proxy_pass 结尾带 / 和不带 / 的区别
2.1 场景假设
在 Nginx 的配置文件 nginx.conf 中,proxy_pass
有以下两种使用场景:
- 使用场景一:
proxy_pass
结尾带/
:
nginx
location /test/ {
proxy_pass http://localhost:8080/;
}
- 使用场景二:
proxy_pass
结尾不带/
:
nginx
location /test/ {
proxy_pass http://localhost:8080;
}
下面我们来详细介绍一下完整的验证过程。
2.2 实战验证
在验证之前,我们先用 Java 编写两个测试 API接口:
DemoController.java
java
import com.demo.common.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class DemoController {
@GetMapping("/demo/findById")
public Result<Object> demoFindById(Integer id, HttpServletRequest request) {
String msg = ">>>>>>>>>>【INFO】请求URI:" + request.getRequestURI() + ",请求URL:" + request.getRequestURL() + ",id:" + id;
return Result.succeed().setMessage(msg);
}
@GetMapping("/test/demo/findById")
public Result<Object> testDemoFindById(Integer id, HttpServletRequest request) {
String msg = ">>>>>>>>>>【INFO】请求URI:" + request.getRequestURI() + ",请求URL:" + request.getRequestURL() + ",id:" + id;
return Result.succeed().setMessage(msg);
}
}
验证1:结尾带/的场景
nginx.conf 中配置如下:
nginx
location /test/ {
proxy_http_version 1.1;
proxy_pass http://localhost:8080/;
access_log test-access.log;
error_log test-error.log;
}
启动 Nginx:
请求如下地址:
请求结果,如下所示:
可以看到,proxy_pass http://localhost:8080/;
配置会 截断匹配成功的location规则(/test),然后将剩余的 URI进行转发(/demo/findById)。
验证2:不带/的场景
nginx.conf 中配置如下:
nginx
location /test/ {
proxy_http_version 1.1;
proxy_pass http://localhost:8080;
access_log test-access.log;
error_log test-error.log;
}
重载 Nginx 配置:
再次请求如下地址:
请求结果,如下所示:
可以看到,proxy_pass http://localhost:8080/;
配置会 保留匹配成功的location规则(/test),然后将完整的 URI进行转发(/test/demo/findById)。
2.3 结论
最终验证后结论如下:
proxy_pass
结尾带/
的场景中,会截断匹配成功的location规则,转发剩余的 URI。
配置: proxy_pass http://localhost:8080/
转发前: {nginx地址}/test/demo/findById?id=1
转发后: http://localhost:8080/demo/findById?id=1
proxy_pass
结尾不带带/
的场景中,会保留匹配成功的location规则,并且转发剩余的 URI。
配置: proxy_pass http://localhost:8080
转发前: {nginx地址}/test/demo/findById?id=1
转发后: http://localhost:8080**/test**/demo/findById?id=1
补充:Nginx的相关命令(Windows)
start nginx -- 启动Nginx
nginx -c /usr/local/nginx/conf/nginx.conf -- 启动Nginx,-c参数指定了要加载的nginx配置文件路径
nginx -t -- 测试配置是否正确
nginx -t -c /path/to/nginx.conf -- 测试指定nginx配置文件是否正确
nginx -s reload -- 重新加载Nginx的配置信息(注意:修改配置文件后要清除temp文件夹下的文件,再重新加载)
nginx -s stop -- 停止Nginx(立即停止)
nginx -s quit -- 停止Nginx(优雅停止)
nginx -s reopen -- 重新打开日志(用于更改日志文件名之后,将日志写入到新的日志文件中)
tasklist /fi "imagename eq nginx.exe" -- 查看Nginx相关进程
taskkill /im nginx.exe /f -- 杀掉Nginx相关进程