在Production的環境下,我們會想要將我們的NodeJS所架設出來的Server給代理到Nginx或者Apache這種專業的Http server上。很多人可能會好奇,Express或Koa本身就有http的功能了,為何需要多此一舉,反向代理反而還多了一層架構。

我認為多了這個Nginx前端有下面幾點好處

  1. Port 80與Port 443只有一個,如果我們有多個不同的網站程式需要架設,就會遇到Port衝突的問題,例如近期內崛起的純前端框架,背後需要一個後端API支援,如果兩者都想要架設在https上,使用Proxy_pass是良好的解決方案。
  2. 前端網頁需要進行AJAX時會遇到CORS問題,我們可以透過proxy的方式來規避掉這個問題
  3. 使用Nginx來控管靜態檔案,讓我們不用處理Cache等問題。
  4. Nginx可以跑在多個Thread或者Process上,處理Load balance上也十分容易

因為有著上述的優點,所以通常在Production環境時,我們會選擇用Nginx當成前端,通過Router的配置,以及Proxy的轉發,讓我們可以架設多種後端程式。

image

因此如何設定Nginx就更為重要,接下去我們就做個簡單的範例,設計一個api路由,導到NodeJS程式,而NodeJS程式開在本地的Port3000上。

    
server{
    listen 80;
    server_name www.myhome.com;

    location / {
        root /var/www;
    }

    location /api/ {
        rewrite ^/api/(.*) /$1 break;
        proxy_pass http://127.0.0.1:3000;
    }
}

探討幾個重點

  1. 第10行: 我們用正規表達式改寫我們請求的路由,通常我們在撰寫程式的時候,我們都會以本身程式為root的觀點下去寫,但是我們這邊多了一個/api的前綴路由。因此我們必須用rewrite改寫他,因此我們的Nginx接收到/api/users會將它改寫成/users再丟回給NodeJS程式執行。這邊有一個小陷阱,當Nginx Rewrite時他會重新匹配Location,做到重導向的功能,我們不想要他這樣做,因此使用break告訴他不需要重導向。
  2. 第11行: 使用proxy_pass將我們的請求導向http://127.0.0.1:3000

References:
1. nginx 配置之 proxy_pass 神器!
2. Using Node.js only vs. using Node.js with Apache/Nginx