nginx如何做到TCP的負載均衡


 
TCP 的 負載均衡
 
這個片段描述了如何通過nginx plus進行負載均衡
 
在版本5中,nginx plus 能夠代理和負載均衡通過TCP路徑,TCP對於一些流行應用和服務是一個協議:LDAP、MYSQL、RTMP
 
stream 模塊
 
TCP 負載均衡被nginx的三個模塊所實現,而且這些模塊被嵌入在nginx plus中。
它們定義的命令是在stream配置塊中:
先決條件
  • nginx plus 版本5(具備基本功能)或者版本6(在這個文章有描述的功能)
  • 一個應用、數據庫、服務進行通信都是通過TCP的方式
  • 負載均衡服務中的每個服務都需要運行一個實例
配置TCP負載均衡
 
負載均衡涉及到了高效的分發網絡到后台服務,要配置負載均衡,需要執行下面的技術:
  1. 創建最高級別的stream(與http同一級別)上下文在nginx plus配置當中。
  2. 定義一個upstream組,由多個服務組成達到負載均衡
  3. 定義一個服務用來監聽TCP連接,並且把他們代理到一個upstream組中
  4. 配置負載均衡的方法和參數為每個server;配置些如:連接數、權重、等等
創建一個upstream組
 
首先創建一個server組,用來作為TCP負載均衡組。定義一個upstream塊在stream上下文中
在這個塊里面添加由server命令定義的server,指定他的IP地址和主機名(能夠被解析成多地址的主機名),和端口號。注意:你不能為每個server定義協議,因為這個stream命令建立TCP作為整個
server的協議了。下面的例子是建立一個被稱之為stream_backend組,兩個監聽12345端口的server
,一個監聽12346端口。
 
stream {
     upstream stream_backend {
          server backend1.example.com:12345 weight=5;
          server backend2.example.com:12345;
          server backend3.example.com:12346;
     }
}
 
下面的片段中,你定義每個server為單獨的組中。然后你能自定義upstream組的配置,而這些
組是通過負載均衡的算法來進行分組的,或者是能健康的管理。. See  Choosing a Load Balancing Method和后續的片段.
 
TCP的代理通信
 
配置反向代理使nginx plus能夠把TCP請求從一個客戶端轉發到負載均衡組中。在每個server配置塊中
通過每個虛擬server的server的配置信息和在每個server中定義的監聽端口的配置信息和proxy_passs
命令把TCP通信發送到哪個server中去。
 
stream {
     server {
          listen 12345;
          proxy_pass stream_backend;
     }
}
 
一個另類的方式是代理TCP通信到單一的server中而不是server組中。
假如你的server的唯一標識是通過主機,而且你的主機名是可以解析成多個IP地址的話,然而nginx的負載均衡通信通過使用round-robin算法得到的IP方式。在這種情況下,你必須還要附加端口號來標識到底哪個server來處理的。
 
stream {
     server {
          listen 12345;
          proxy_pass backend4.example.com:12345;
     }
}
 
改變負載均衡的方法
 
默認nginx plus是通過輪詢算法來進行負載均衡的通信的。引導這個請求循環的到配置在upstream組中server端口上去。
因為他是默認的方法,這里沒有輪詢命令,只是簡單的創建一個upstream配置組在這兒stream山下文中,而且在其中添加server。
 
upstream backend {
     server backnd1.example.com:12345 weight;
     server backedn2.example.com:12345;
     server backend3.example.com:12345;
}
 
配置不同的負載均衡的算法,囊括在upstream配置塊中。
  1. least-connected :對於每個請求,nginx plus選擇當前連接數最少的server來處理
upstream stream_backend {
     least_conn;
     
     server backend1.example.com:12345 weight=5;
     server backend2.example.com:12345;
     server backend3.example.com:12346;
}
 
2.  least time :對於每個鏈接,nginx pluns 通過幾點來選擇server的:
  • 最底平均延時:通過包含在least_time命令中指定的參數計算出來的:
  1. connect:連接到一個server所花的時間
  2. first_byte:接收到第一個字節的時間
  3. last_byte:全部接收完了的時間
  • 最少活躍的連接數
 
upstream stream_backend {
     least_time first_byte;
 
     server backend1.exmaple.com:12345 weight=5;
     server backend2.example.com:12345;
     server backend3.example.com:12346;
}
 
3. 普通的hash算法:nginx plus選擇這個server是通過user_defined 關鍵字,就是IP地址:$remote_addr;
 
upstream stream_backend {
     hash $remote_addr consistent;
     
     server backend1.example.com:12345 weight=5;
server backend2.example.com:12345;
server backend3.example.com:12346;
}
這個可選的consistent參數應用這個一致性hash算法,這種方法能減少使由於server添加或者刪除導致的關鍵字映射到其他服務器上的可能性。
 
配置session的持久化
 
配置session的持久化使用hash負載均衡的方式在前面已經描述了。因為hash函數是建立在客戶端的IP地址上的,所以TCP請求從一個到同樣一個server是非常可能的,除非這個server不可用了
 
限制連接數
 
可以設置nginx plus與server所建立的連接數:server max_conns=?
upstream stream_backend {
     server backend1.example.com:12345 weight=5;
     server backend2.example.com:12345;
     server backend3.example.com:12346 max_conns=4;
}
 
不好的健康監測
     假如連接一個server超市了或者導致一個錯誤,nginx plus標識這個server是無效的和阻止請求到那個server上去,在一段時間內。下面的參數是用來判斷哪些server才算是不可達的:
  • fail_timeout :在這個時間段中進行了多少次連接的嘗試失敗了,那么就認為是不可達了並標記不可達
  •  max_fails:和上面是對應上的。
默認是在10秒鍾進行1次嘗試。在10秒進行至少一次嘗試是失敗的,那么nginx則認為這個server是不可達的
下面的例子中要求是:30s進行2次嘗試失敗認為server不可達
upstream stream_backend {
     server backend1.example.com:12345 weight=5;
     server backend2.example.com:12345 max_fails=2 fail_timout=30; //當個server的不健康的監測
     server backend3.example.com:12346 max_conns=4;
}
 
好的健康監測
 
當你進行健康監測的時,nginx plus平凡的進行TCPupstream的server的測試通過響應為了避免失敗。
健康監測可以配置成監測失敗類型的范圍。
 
how it works?
nginx plus 發送一個健康監測請求到每個TCP upstream server中去,監測響應是否滿足這個指定的條件,假如一個連接不能連接到某個server當中去,這個健康監測就會失敗,這個server將會被考慮成不監控了。nginx plus就不會代理客戶端連接到不健康的server中去,假如幾個server被監測為健康的,那么相反的server就是不健康的了
 
先決條件:
  • 你已經定義了一組server在stream上下文中:例如:
stream {
     upstream stream_backend {
          server backend1.example.com:12345; 
          server backend2.example.com:12345; 
          server backend3.example.com:12345;
     }
}
 
  • 你也做好了定義一個TCP連接的代理server
server {
     listen 12345;
     proxy_pass stream_backend;
}
 
基本的配置
  1. 添加一個zone命令在upstream中,這個zone定義的大小是用來給worker processes存放connections和counters用的

    stream {
         upstream stream_backend {
              zone stream_backend 64k;
              server backend1.exmaple.com:12345;
                   ..........
         }
    }
  2. 添加 health_check and health_check_timeout命令到代理的server中去、
    server {
        listen 12345;
        proxy_pass strean_backend;
        health_check;
        health_check_timeout 5s;
    }

    這個health_check命令將會激活這個健康監測功能,當又health_check_timeout 將會覆蓋掉這個proxy_timeout的值,
    作為健康監測超時時間應該是顯著縮短。

fine-tuning 健康監測
 
默認,nginx plus試着再每5s中連接每個server在upstream server組中。假如連接不能夠被建立,nginx plus認為這個健康監測失敗,標識他為不健康。停止連接該server。
改變默認的行為,包括的參數如下:
  • interval :多少秒會發送健康請求
  • passses : 多少連續的響應才算被考慮為健康的
  • fails :多少次連續的失敗響應才考慮為不健康的
server {
     listen 12345;
     proxy_pass stream_backend;
     health_check insterval=10 passes=2 fails=3; //整體server檢測
}
在這個例子中這個時間周期變成了10s;三次連續無響應被考慮為不健康,假如連續兩次檢測正常可能為server正常
 
fine-tuning health check with the macth configuration block
 
定義一些測試的種類去驗證server響應從而達到server是否健康,定義這些種類在一個match的配置塊中
這個match在stream上下文中;
使用下面的參數在match塊中是需要的目的為了health_check而定制的條件
  • send :發送到server的字符創
  • expect :返回的數據必須匹配這個正則表達式
這些參數可以隨意的組合,但是不會超過一個send或者一個expect參數同一時間內,下面是這兩個參數的搭配:
  • 既沒有send也沒有expect參數被指定。連接server的能力是測試的
  • 指定了expect,然后server被期待無條件的發送一條數據過來
    match pop3 {
        expect ~*"\+OK";
    }
  • send被指定,然后期待連接將會成功的建立,指定的字符串會被發送到server端
    match pop_quit {
       send QUIT;
    }
  • 假如兩個都有,那么這個發送參數返回的值必須匹配這個expect指定的正則
stream {
     upstream stream_backend {
          zone upstream_backend 64k;
          server backend1.example.com:12345;
     }
     match http {
          send "GET / HTTP/1.0\r\nHost:localhost\r\n\r\n"
          expect ~*"200 OK";
     }
     
     server {
          listen 12345;
          health_check match=http;
          proxy_pass stream_backend;     
     }
 
}
 
運行時的重新配置
 
upstream 服務組能夠非常容易的重配在運行的時候通過一個簡單的http接口,使用這個接口,你將會能夠
看到所有的服務,某個服務的詳細信息,或者對server的增刪。
為了能夠在運行時重配,你需要如下條件:
 
授予訪問upstream_conf handler -a 特殊的handler權限;handler能夠檢查和重配upstream組在nginx plus中。作如上的操作需要在http 快中,使用upstream_conf命令 在一個分開的location中
對於訪問這個location需要限定。
http {
     server {
          location /upstream_conf {
               upstream_conf;
               
               allow 127.0.0.1; #permit access from localhost
               deny all;#deny; access from everywhere else
          }
     }
}
 
在這個stream塊中,指定zone對於這個server組來說需要;這個命令將會創建一個zone大小的在共享內存當中,在里面保存了server組的配置;這樣所有的workprocesses就能夠共享同一個配置了。
 
stream {
     ...
     #Configuration of an upstream server group
     upstream appservers {
          zone appservers 64k;
          
          server appserv1.example.com:12345 weight=5;
          server appserv2.example.com:12345 fail_timeout=5s;
          
          server backup1.example.com:12345 backup;
          server backup2.example.com:12345 backup;
     }
     
     server {
          #server that proxies connections to the upstream
          proxy_pass appservers;
          lealth_check;
     }
}
 
http {
...
     server {
          #location for configuration requests
          
          location /upstream_conf {
               upstream_conf;
               allow 127.0.0.1;
               deny all;
          }
     }     
}
 
這里,想訪問這個location只有是本地的IP才可以,而其他的IP都被屏蔽了。想發送一個配置命令到nginx中,發送一個http請求可以帶很多配置信息。這個請求應該應該有一個適合的uri進入到包含了upstream_conf的location中,這個請求應該包括了設置server組的upstream的參數。
 
例如:查看所有的備份server,對於這server來說就是:http://127.0.0.1/upstream_conf?stream=&upstream=appservers&backp=
 
增加一個新的server到組中,發送一個請求攜帶了add和server參數:http://127.0.0.1/upstream_conf?stream=&add=&upstream=appservers&server=appserv3.example.com:12345&weight=2&max_fails=3
 
移除一個server,發送一個請求攜帶remove命令和server唯一標識的參數ID
 
去修改一個特定的server參數,發送一個請求攜帶ID和參數信息
 
 
 
 
tcp load balancing 配置例子
 
這個配置例子是TCP負載均衡的例子在nginx plus中的
 
stream {
     
     upstream stream_backend {
          least_conn;
          server backend1.example.com:12345 weight=5;
          server backend2.example.com:12345 max_fail=2 fail_timeout=30s;
          server backend3.example.com:12346 max_conns =3;
     }     
     
     server {
          listen 12345;
          proxy_connect_timeout 1s;
          proxy_timeout 3s;
          proxypass stream_backend ;     
     }
     
     server {
          listen 12346;
          proxy_pass backend4.example.com:12346;
     }
}
 
 
在這個例子中,有兩個servers 他們被定義在server塊中。所有的TCP代理相關的函數都被定義在stream塊中像http塊一樣對待http請求的處理。
 
這第一個server監聽12345端口而且代理所有的TCP連接到這個被命令為backend組中server。注意這個proxy_pass命令定義
這個stream模塊的上下文必須不包含協議。這兩個可選的timeout參數被指定如下含義:proxy_connect_timeout設置建立一個連接與某個server的請求的超時時間,而proxy_time是代理已經建立之后的超時時間。
 
這個backend組由三個運行同樣內容的,每個server命令后綴一個固定的端口號。連接被分配到每個server中去,而這種分配方式是:最少連接數。
 
這第二個虛擬server監聽在12346端口號上,並且代理TCP連接到backend4邏輯server上,這個server或許被解析到一個serverIP上,而且這個地址將會做輪詢的方式負載均衡。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM