1. 程式人生 > >使用nginx反向代理髮布多個域名80埠的WEB服務

使用nginx反向代理髮布多個域名80埠的WEB服務

在對外提供WEB頁面服務時,提供的域名通常需要隱藏埠號和專案名,例如像www.baidu.com。隱藏埠容易處理,將WEB容器的埠號修改為80即可滿足。如果要隱藏專案的名稱,在tomcat下,可以通過在server.xml中加入以下語句,在不輸入專案名的情況下,自動進入www.abc.com/websit對應的web服務。

<Context path="" docBase="/usr/local/tomcat/webapps/website" />

      另外如果想在一臺伺服器上部署多個WEB服務,也可以採用這種方式,並結合tomcat虛擬主機配置實現。

  虛擬主機在本文中不再贅述,這裡要講是使用nginx來實現該功能。

      這種場景下的解決方案是利用nginx的反向代理功能,通過配置nginx,可以將訪問80埠、單域名不同的請求對映到WEB容器上不同的專案上,甚至WEB容器的埠號都可以不設定為80,因為常常nginx和WEB容器部署到同一臺伺服器上,這是80埠必須分配給nginx才能監聽到不到埠域名的訪問。nginx的配置內容如下所示:

複製程式碼
server {
    listen       80;
        server_name  www.aaa.con aaa.con;
        location / {
         proxy_pass   http://www.aaa.con:8087/proj1/;
        }
     location /proj1/ {   proxy_pass http://www.aaa.con:8087/proj1/;     } }
server {
  listen 80; 
  server_name www.bbb.con bbb.con; 
  location / { 
    proxy_pass http://www.aaa.con:8087/proj2/;
  }

  location /proj2/ {
    proxy_pass http://www.aaa.con:8087/proj2/;
  }
 }
複製程式碼

      這段配置的意思是訪問www.aaa.com或者aaa.com的請求,會被nginx對映到http://www.aaa.con:8087/proj1/;而訪問www.bbb.com或者bbb.com的請求,會被對映到http://www.aaa.con:8087/proj2/。多配置location /proj1/的原因是避免CSS/JS等在html中設定了專案名路徑的資源因為nginx的反向代理造成丟失工程名而無法訪問到資源。

      這樣,我們就能夠在一臺機器上釋出針對若干個域名的WEB服務了。

注:有些應用必須設定proxy_set_header屬性,否則無法正常使用(比如使用dwr框架的javaee應用),示例:

  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.     }  

原因如下:

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不被重寫的失誤。