来源 | 互联网全栈架构
Nginx作为一款高性能的HTTP和反向代理服务器,现在几乎成了软件开发中的必备技能,特别是在java web应用程序中,基本上变成了标准配置,它经常用来作为反向代理,以提升系统的吞吐量和可用性。然而,Nginx里面有一个默认配置有点“反常识”,如果没有碰到过这种情况,或者经验不够丰富,很有可能会掉到坑里。我们用实际的案例来演示一下,首先写一个spring boot的接口,它的功能很简单,就是返回Hello World字符串:
package com.fullstack.commerce.user.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/hello")
public class
HelloWorldController {
@GetMapping("world")
public String sayHello(HttpServletRequest request){
return "Hello World!";
}
}我们用Postman来测试,先验证一下结果(服务器的端口为8081):
没问题,工作得很好,输入正确的地址,接口就返回了Hello World字符串,这就是我们想要的。随着开发工作的深入推进,这时候需要在请求头里面加一下参数,并在后端接口做相应的处理。比如在请求头里加上参数cur_location,我们继续使用Postman来测试:这次是在header里面加了一下参数,我们看看这时后端的接口是什么情况,使用debug模式,并且打上断点,我们可以看到,请求头中的参数cur_location有值,而且是我们在Postman中指定的,完全符合我们的预期:代码就写到这里了,平平无奇,也很简单。接下来我们就引入了Nginx,它的功能也很简单,就是把前端的请求转发一下,主要的配置如下:location / {
proxy_pass http://localhost:8081/;
}
Nginx其他的配置项没有改变,然而,奇怪的事情发生了,当我们继续用Postman来测试的时候(请求内容跟上次一样,没有任何改变),发现后端接口没有收到cur_location:稍微留意一下,请求地址的端口变成了80,这个时候request先打到nginx,然后nginx再转发到后端8081的接口。我们依然在后端代码中打个断点:神奇的是,请求头中的cur_location竟然没有值,这个参数名看起来也没有什么特别的啊,也不是什么关键字之类的。经过一番探索才发现,Nginx默认会忽略请求头中带下划线的参数:如果需要打开这个参数,在nginx.conf进行配置即可:
underscores_in_headers on;重启一下nginx,再次发送请求,后端接口就可以正常解析了。-