Nginx筆記(四)

代理一組服務器
  • 使用upstream指令來定義一組服務器,指令放在http context里
    • 如:

      http {
          upstream backend {
              server backend1.example.com weight=5;
              server backend2.example.com;
              server 192.0.0.1 backup;
          }
      }
      
  • 使用proxy_pass指令把請求打到被代理的服務器上
    • 如:

      server {
          location / {
              proxy_pass http://backend;
          }
      }
      
選擇一種負載均衡方法
  1. 默認的是權重輪詢算法,nginx會按照各個server的權重比來分發請求。
    • 如:

      upstream backend {
         server backend1.example.com;
         server backend2.example.com;
      }
      
  2. 最少連接法:每次都選擇連接數組少的server,如果有多個server的連接數相同,再根據這幾個server的權重分發請求。
    • 例:

      upstream backend {
          least_conn;
      
          server backend1.example.com;
          server backend2.example.com;
      }
      
  3. ip哈希:使用IPv4的前三個八字節位或者IPv6的全部來計算哈希值,所以相同地址的請求始終會打到相同的Server上,除非這個server不可用。
    • 如果一個server需要暫時移除,使用down參數來避免請求打到這臺機器上,應該哈希到這臺機器上的請求會自動的發送到組里的下一臺。

    • 如:

      upstream backend {
          ip_hash;
      
          server backend1.example.com;
          server backend2.example.com;
          server backend3.example.com down;
      }
      
  4. 哈希:使用自定義的key去進行哈希計算。
    • 通過consistent參數使用ketama一致哈希算法來減少增減服務器對客戶端的影響。
      • 例:

        upstream backend {
            hash $request_uri consistent;
        
            server backend1.example.com;
            server backend2.example.com;
        }
        
      • 上面的就是通過uri進行哈希計算。

  5. 最小響應時間:對于每個請求,nginx選擇平均等待時間最小并且連接數最少的。
    • 通過least_time的參數來確定平均等待時間的計算方式。

      • header: Time to receive the first byte from the server
      • last_byte: Time to receive the full response from the server
    • 如:

      upstream backend {
          least_time header;
      
          server backend1.example.com;
          server backend2.example.com;
      }
      
服務器權重
  • 默認的權重是1,通過weight參數來指定權重值。

  • 通過backup來標記備用服務器,如果其他的都宕機了,請求會打到備用的服務器是上。

  • 例:

    upstream backend {
        server backend1.example.com weight=5;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
    
服務器慢啟動
  • 對于剛剛恢復的服務器,如果一下子被請求淹沒可能會再次宕機。

  • 可以通過server指令的slow_start參數來讓其權重從0緩慢的恢復到正常值。

  • 例:

    upstream backend {
        server backend1.example.com slow_start=30s;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
    
  • 注意如果一個組里面只有一個server,那么max_fails,fail_timeout和slow_start參數都會被忽略。并且這個服務器永遠都不會被認為是不可用的。

Enabling Session Persistence
  • Session持久性是指nginx識別客戶端的session然后把同一個session的請求路由到同一個server上。
  • nginx支持三種session持久的方法,通過sticky指令去設置。
    • sticky cookie方法。通過這種方法,當server第一個響應的時候,nginx添加一個cookie來標識是哪個server響應的,當它下次請求的時候,會帶著cookie,nginx會把請求路由到同一臺server。

      • 例:

        upstream backend {
            server backend1.example.com;
            server backend2.example.com;
        
            sticky cookie srv_id expires=1h domain=.example.com path=/;
        }
        
    • sticky_route方法,使用這種方法,nginx第一個收到請求的時候會給客戶端下發一個路由。后續的請求都會帶著路由參數,nginx再來判斷請求該打到哪個server上。路由信息可以通過cookie或者uri獲取到。

      • 例:

        upstream backend {
            server backend1.example.com route=a;
            server backend2.example.com route=b;
        
            sticky route $route_cookie $route_uri;
        }
        
    • cookie learn 方法。通過這種方法,nginx通過檢測請求和響應來尋找session標記。通常,這些標記通過cookie傳遞。如果一個請求的包含的session標記已經learned,nginx將會把請求打到正確的server上。

    • 例:

      upstream backend {
         server backend1.example.com;
         server backend2.example.com;
      
         sticky learn 
             create=$upstream_cookie_examplecookie
             lookup=$cookie_examplecookie
             zone=client_sessions:1m
             timeout=1h;
      }
      
    • 在這個例子中,server通過在響應中設置一個"EXAMPLECOOKIE"來標記一個session。

    • create的參數指定一個變量來指示一個session的創建,在這個例子中,server發送"EXAMPLECOOKIE"表示新的session建立。

    • lookup的參數指定如何尋找一個已經存在的session,在這個例子中,通過查找客戶端的"EXAMPLECOOKIE"來搜索現有的session。

    • zone 指定一塊共享的內存來保存sticky sessions的信息。上個例子中,這塊空間叫做client_sessions,大小為1M。

限制連接數量
  • 可以通過max_conns參數來限制連接數,如果達到了最大連接數,請求就可以放到通過queue指令生命的隊列中來等待后續的處理 ,queue指令設置了可以放到隊列中得最大的請求數、

  • 例:

    upstream backend {
        server backend1.example.com  max_conns=3;
        server backend2.example.com;
    
        queue 100 timeout=70;
    }
    
  • 如果隊列排滿或者在可選參數timeout設置的時間內無法選擇上游服務器,客戶端將接到一個錯誤。

  • 注意如果閑置的keepalive連接在另一個worker processes中打開了max_conns限制會被忽略。導致的結果是,在多個工作進程共享內存的配置中,連接的總數可能會超過max_conns的值。

被動的健康監測
  • 當nginx認為一個server不可用,它會暫時停止向這個server轉發請求直至nginx再次認為它是可用的。

  • nginx通過兩個參數來控制nginx的判斷

    • fail_timeout,當在fail_timeout時間段內,失敗次數達到一定數量則認為該server不可用。并在接下來的fail_timeout時間內不會再將請求打到這個server上。 - max_fails,這個max_fails就是上面說的失敗的一定數量。
  • 默認的值是10秒和1次嘗試。

  • 例:

    upstream backend {                
        server backend1.example.com;
        server backend2.example.com max_fails=3 fail_timeout=30s;
        server backend3.example.com max_fails=2;
    }
    
主動的心跳檢測
  • 使用health_check指令來檢測server是否可用,除此之外還要使用zone指令。

  • 例:

    http {
        upstream backend {
            zone backend 64k;
    
            server backend1.example.com;
            server backend2.example.com;
            server backend3.example.com;
            server backend4.example.com;
        }
    
        server {
            location / {
                proxy_pass http://backend;
                health_check;
            }
        }
    }
    
  • 在上個例子中,nginx每五秒請求一次backend組里的每臺機器,請求地址是"/",如果失敗或者超時(或者返回的狀態碼不是2xx或者3xx),nginx就認為這個server宕機了。nginx將停止向它轉發請求,直至其再次通過心跳檢測。

  • 可以通過參數控制health_check指令的行為。

  • 例:

    location / {
        proxy_pass http://backend;
        health_check interval=10 fails=3 passes=2;
    }
    
  • 上個例子是每十秒檢測一次,如果失敗了3次就認為宕機了,如果成功2次就認為通過了檢測。

  • 也可以檢測特定的uri

  • 例:

    location / {
        proxy_pass http://backend;
        health_check uri=/some/path;
    }
    
  • 通過match塊自定義成功的狀態。

    http {
        ...
    
        match server_ok {
            status 200-399;
            body !~ "maintenance mode";
        }
    
        server {
            ...
    
            location / {
                proxy_pass http://backend;
                health_check match=server_ok;
            }
        }
    }
    
  • 上個例子中要求status在200到399之間,并且body滿足提供的正則表達式。

  • match塊中可以包含一個status的狀態,一個body的狀態和多個header的狀態。

    match welcome {
        status 200;
        header Content-Type = text/html;
        body ~ "Welcome to nginx!";
    }
    
  • 使用!

    match not_redirect {
        status ! 301-303 307;
        header ! Refresh;
    }
    
  • 上個例子表示status不是301、302、303或者307,并且header中不包含Refresh。

至此Nginx筆記結束,了解了這些后,對于看懂一個Nginx的配置,了解Nginx能夠實現什么功能和對其進行小改應該會有一定的幫助。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容