1. 程式人生 > >架構師日記——Nginx反向代理、動靜分離和負載均衡

架構師日記——Nginx反向代理、動靜分離和負載均衡

反向代理

反向代理可以理解為客服端和服務端溝通經過一個代理,代理來分發請求
Nginx通常被用作後端伺服器的反向代理,這樣就可以很方便的實現動靜分離,以及負載均衡,從而大大提高伺服器的處理能力。

常用配置

location /{
    proxy_pass http://127.0.0.1:8080
}

upstream abc.com{
    server 127.0.0.1:8080 weight=5;
}
location /{
    proxy_pass http://abc.com
}

第二種配置方式用了upstream,可以為之後負載均衡做準備

動靜分離

動靜分離,動態內容如php,jsp的頁面必須由服務端動態處理,就轉發到tomcat之類的容器,靜態內容如圖片,html就直接訪問檔案
Nginx實現動靜分離,其實就是在反向隊裡的時候,如果是靜態資源,那麼就直接從Nginx釋出的路徑去讀取,而不需要從後臺伺服器後去了
注意

:這種情況下需要保證後端跟前端的程式保持一致,可以Rsync做服務端自動同步或者使用NFS、MFS分散式共享儲存

如:

localtion ~"."\.(jpg|jpeg|gif|png|swf|ico)${
    root /usr/common/tomcat/webapps
}

匹配jpg|jpeg|gif|png|swf|ico字尾的檔案就直接在root的路徑找

負載均衡

Nginx通過upstream模組來實現簡單的負載均衡

常用指令

ip_hash

語法:ip_hash
預設值:none
使用欄位:upstream
這個指令將基於客戶端連線的IP地址來分發請求。
雜湊的關鍵字是客戶端的C類網路地址,這個功能將保證這個客戶端請求總是被轉發到一臺伺服器上,但是如果這臺伺服器不可用,那麼請求將轉發到另外的伺服器上,這將保證某個客戶端有很大概率總是連線到一臺伺服器。
無法將權重(weight)與ip_hash聯合使用來分發連線。如果有某臺伺服器不可用,你必須標記其為“down”,如下例:

upstream backend {
  ip_hash;
  server   backend1.example.com;
  server   backend2.example.com;
  server   backend3.example.com  down;
  server   backend4.example.com;
}

注意:即使是由同一臺機子發出的請求也不一定訪問到同一個伺服器,可能這臺機子也使用了代理,使ip發生變化,或者訪問的伺服器down掉了

server

語法:server name [parameters]
預設值:none
使用欄位:upstream
指定後端伺服器的名稱和一些引數,可以使用域名,IP,埠,或者unix socket。如果指定為域名,則首先將其解析為IP。

  • weight = NUMBER - 設定伺服器權重,預設為1。
  • max_fails = NUMBER - 在一定時間內(這個時間在fail_timeout引數中設定)檢查這個伺服器是否可用時產生的最多失敗請求數,預設為1,將其設定為0可以關閉檢查,這些錯誤在proxy_next_upstream或fastcgi_next_upstream(404錯誤不會使max_fails增加)中定義。
  • fail_timeout = TIME - 在這個時間內產生了max_fails所設定大小的失敗嘗試連線請求後這個伺服器可能不可用,同樣它指定了伺服器不可用的時間(在下一次嘗試連線請求發起之前),預設為10秒,fail_timeout與前端響應時間沒有直接關係,不過可以使用proxy_connect_timeout和proxy_read_timeout來控制。
  • down - 標記伺服器處於離線狀態,通常和ip_hash一起使用。
  • backup - (0.6.7或更高)如果所有的非備份伺服器都宕機或繁忙,則使用本伺服器(無法和ip_hash指令搭配使用)。
    示例配置
upstream  backend  {
  server   backend1.example.com    weight=5;
  server   127.0.0.1:8080          max_fails=3  fail_timeout=30s;
  server   unix:/tmp/backend3;
}

注意:如果你只使用一臺上游伺服器,nginx將設定一個內建變數為1,即max_fails和fail_timeout引數不會被處理。
結果:如果nginx不能連線到上游,請求將丟失。
解決:使用多臺上游伺服器。

upstream

語法:upstream name { … }
預設值:none
使用欄位:http
這個欄位設定一群伺服器,可以將這個欄位放在proxy_pass和fastcgi_pass指令中作為一個單獨的實體,它們可以可以是監聽不同埠的伺服器,並且也可以是同時監聽TCP和Unix socket的伺服器。
伺服器可以指定不同的權重,預設為1。
示例配置

upstream backend {
  server backend1.example.com weight=5;
  server 127.0.0.1:8080       max_fails=3  fail_timeout=30s;
  server unix:/tmp/backend3;
}

請求將按照輪詢的方式分發到後端伺服器,但同時也會考慮權重。
在上面的例子中如果每次發生7個請求,5個請求將被髮送到backend1.example.com,其他兩臺將分別得到一個請求,如果有一臺伺服器不可用,那麼請求將被轉發到下一臺伺服器,直到所有的伺服器檢查都通過。如果所有的伺服器都無法通過檢查,那麼將返回給客戶端最後一臺工作的伺服器產生的結果。

Geo和GeoIP模組

這兩個模組主要用於做全域性的負載均衡,可以根據不同的客戶端來訪問不同的伺服器,示例如下

http{
    geo $geo{
        default default;
        202.103.10.1/24 A;
        179.9.0.3/24 B;
    }
    upstream default.server{
        server 192.168.0.100;
    }
    upstream A.server{
        server 192.168.0.101;
    }
    upstream B.server{
        server 192.168.0.102;
    }
    server{
        listen 80;
        location /{
            proxy_pass http://$geo.server$request_uri;
        }
    }
}