網絡結構描述:
1個Nginx(前端)+2個tomcat(後端)
環境:
公司内網(網段:192.168.1.0/24),伺服器也是配置設定的内網ip:192.168.1.4(暫定);後端兩個tomcat:192.168.1.31/189
網站有session,所有Nginx啟用ip_hash.
現象:
測試組用loadrunner模拟N多内網ip進行壓測系統。發現,這些ip統一都轉發到一個後端。
後經排查發現問題所在(結論最下面)。
1、請看官方解釋:
This directive causes requests to be distributed between upstreams based on the IP-address of the client.
The key for the hash is the class-C network address or the entire IPv6-address of the client. IPv6 is supported for ip_hash since 1.3.2 or 1.2.2. This method guarantees that the client request will always be transferred to the same server. But if this server is considered inoperative, then the request of this client will be transferred to another server. This gives a high probability clients will always connect to the same server. (簡譯:将用戶端ip轉化成C類網絡位址,然後将該網絡位址當作hash關鍵字,來保證這個用戶端請求總是被轉發到一台伺服器上)
2、請看Nginx的ip hash算法(該段代碼為轉發。
主要代碼請看這裡:
<code>for</code><code>( ;; ) {</code><code>for</code><code>(i = </code><code>0</code><code>; i < </code><code>3</code><code>; i++) {</code><code>hash = (hash * </code><code>113</code><code>+ iphp->addr[i]) % </code><code>6271</code><code>; </code>
1、for循環 i 取 012三個值,而ip的點分十進制表示方法将ip分成四段(如:192.168.1.1),但是這裡循環時隻将ip的前三個端作為參數加入hash函數。這樣做的目的是保證ip位址前三位相同的使用者經過hash計算将配置設定到相同的後端server。
作者的這個考慮是極為可取的,是以ip位址前三位相同通常意味着來着同一個區域網路或者相鄰區域,使用相同的後端服務讓nginx在一定程度上更具有一緻性。
通過上述解釋,已經基本判斷出問題所在了。。
主要原因就是,公司區域網路用的192.168.1.0/24 C類位址,這樣Nginx在ip_hash(for循環後三個參數統一計入hash值)的時候,就将該類所有ip都轉發到一個後端了。
另,暈了我半天了。。。不論A類B類C類等網絡位址,Nginx的ip_hash算法都将一個ip位址的前三段作為hash的關鍵字。。(規定)