最近帮朋友做了两个网站,预算很小很小.小到两个网站只能跑在一台512M内存的公网服务器上(tomcat+mysql,由于内存太小了,只能把两个网站部署在同一个tomcat上),每个网站有自己的域名,初步考虑使有nginx做反向代理,把两个域名映射到相应的应用上。因此就有了标题所说的“nginx多域名单服务器单IP单Tomcat不同应用”上的配置问题。Nginx介绍的废话就不多说了,在这里把配置文件贴出来给大家参考一下吧:

域名A:www.a.com的配置文件如下:

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. server {  
  2.     listen       80;  
  3.     server_name  *.a.com;  
  4.     location / {  
  5.         proxy_pass http://localhost:8080/projectA/;  
  6.         proxy_set_header   Host    $host;  
  7.         proxy_set_header   X-Real-IP   $remote_addr;  
  8.         proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  
  9.     }  
  10. }  
域名B:www.b.com的配置文件如下:
[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. server {  
  2.     listen       80;  
  3.     server_name  *.b.com;  
  4.     location / {  
  5.         proxy_pass http://localhost:8080/projectB/;  
  6.         proxy_set_header   Host    $host;  
  7.         proxy_set_header   X-Real-IP   $remote_addr;  
  8.         proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  
  9.     }  
  10. }  

注:(1)有些应用必须设置proxy_set_header属性,否则无法正常使用(比如使用dwr框架的javaee应用),原因如下:

nginx为了实现反向代理的需求而增加了一个ngx_http_proxy_module模块。其中proxy_set_header指令就是该模块需要读取的配置文件。在这里,所有设置的值的含义和http请求同中的含义完全相同,除了Host外还有X-Forward-For。
        Host的含义是表明请求的主机名,因为nginx作为反向代理使用,而如果后端真是的服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败【默认反向代理服务器会向后端真实服务器发送请求,并且请求头中的host字段应为proxy_pass指令设置的服务器】。
        同理,X_Forward_For字段表示该条http请求是有谁发起的?如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。因此,在配置用作反向代理的nginx中一般会增加两条配置,修改http的请求头:
proxy_set_header Host $http_host;
proxy_set_header X-Forward-For $remote_addr;

这里的$http_host和$remote_addr都是nginx的导出变量,可以再配置文件中直接使用。如果Host请求头部没有出现在请求头中,则$http_host值为空,但是$host值为主域名。因此,一般而言,会用$host代替$http_host变量,从而避免http请求中丢失Host头部的情况下Host不被重写的失误。

(2)如果jsp中有basehref = <%=basePath%>,要注意项目的虚拟路径配置,因为basePath是根据以下代码生成的:

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

如果客户端访问的地址没有路径名,比如a.com,而nginx代理访问的实际应用有项目名(即不是部署为根目录), 比如nginx访问的实际地址是10.0.1.15/project,那么根据以上的代码,jsp生成含有项目名的basePath写入html页面,这样客户端得到的页面的basehref会带有项目名,而这样客户端再根据basehref发请求会请求不到内容,因为请求是先放给nginx的。因此需要将项目配置为跟目录(tomcat下为ROOT),或者页面中的链接采用绝对路径,如a href = "/project/*"

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐