壓力測試效能概述

四層負載平衡採用開源軟體LVS(Linux Virtual Server)+ Keepalived的方式實現負載平衡,七層負載平衡由Tengine實現。其中四層監聽經過LVS後直接到達後端伺服器,而七層監聽經過LVS後,還需要再經過Tengine,最後達到後端伺服器。七層比四層多了一個處理環節,因此,七層效能沒有四層效能好。

如果您使用七層監聽進行壓來測試,發現根本跑不上去,掛了兩台ECS的七層負載平衡監聽效能還不如一台ECS的效能,除了七層本身的效能比四層低外,以下情況也可能會造成七層測壓效能低:

  • 用戶端通信埠不足

    尤其容易發生在壓測的時候,用戶端通信埠不足會導致建立串連失敗,負載平衡預設會抹除TCP串連的timestamp屬性,Linux協議棧的tw_reuse(time_wait 狀態串連複用)無法生效,time_wait狀態串連堆積導致用戶端通信埠不足。

    解決方法:用戶端端使用長串連代替短串連。使用RST報文中斷連線(socket設定SO_LINGER屬性),而不是發FIN包這種方式斷開。

  • 後端伺服器accept隊列滿

    後端伺服器accept隊列滿,導致後端伺服器不回複syn_ack報文,用戶端逾時

    解決方法:預設的net.core.somaxconn的值為128,執行sysctl -w net.core.somaxconn=1024更改它的值,並重啟後端伺服器上的應用。

  • 後端伺服器串連過多

    由於架構設計的原因,使用七層負載平衡時,使用者長串連經過Tengine後變成短串連,可能造成後端伺服器串連過多,從而表現為壓測效能上不去。

  • 後端伺服器依賴的應用成為瓶頸

    請求經過負載平衡達到後端伺服器後,後端伺服器本身負載都正常,但由於所有的後端伺服器上的應用又依賴其它應用,比如資料庫,資料庫成為瓶頸,也會引起效能低。

  • 後端伺服器的健康檢查狀態異常

    尤其在壓測的時候容易忽略後端伺服器的健康檢查狀態,如果有後端伺服器健康檢查失敗或者健康檢查狀態經常跳躍(好到壞,又從壞到好,反覆變化)也會導致效能跑不上去。

壓力測試建議

在進行壓力測試,注意如下配置:

  • 壓測負載平衡轉寄能力建議使用短連結

    一般來說壓測除了驗證會話保持,均衡性等功能外,主要想驗證的是負載平衡的轉寄能力,因此使用短連結比較合適,用於測試負載平衡和後端伺服器處理能力。但使用短串連測試時注意上述的用戶端通信埠不足問題。

  • 壓測負載平衡輸送量建議使用長串連,用於測試頻寬上限或特殊業務

    壓測工具的逾時時間建議設定為一個較小值(5秒)。逾時時間太大的話,測試結果會體現在平均RT加長,不利於判斷壓測水位是否已到達。逾時時間調小,測試結果會體現在成功率上,便於快速判斷壓測水位。

  • 後端伺服器提供一個靜態網頁用於壓測,以避免應用邏輯帶來的損耗
  • 壓測時,監聽配置建議如下:
    • 不開啟會話保持功能,否則壓力會集中在個別的後端伺服器。
    • 監聽關閉健康檢查功能,減少健康檢查請求對後端伺服器的訪問請求。
    • 用多個用戶端進行進行壓測最好多於5個,源IP分散,能夠更好的類比線上實際情況。

壓力測試工具建議

不建議您使用Apache ab作為壓力測試工具。

Apache ab在大量並發場景下存在3s,6s,9s階梯式停頓的現象。Apache ab會通過判斷content length來確定請求是否成功,而負載平衡掛載多台後端伺服器時,返回的content length會不一致,導致測試結果有誤。

建議使用阿里雲PTS

可以選擇多個用戶端作為壓力測試源,測試結果清晰,並且可以通過配置監控,獲取壓力測試時後端伺服器的效能資料。

使用PTS簡單壓測樣本

建立一個負載均執行個體,添加兩台ECS執行個體作為後端伺服器,分別建立一個TCP監聽和HTTP監聽,後端通信埠設定為80。ECS伺服器的配置為CPU 1核,記憶體512M使用CentOS 6.3 64位的作業系統。

  1. 安裝Apache Web Server提供Web服務。
    yum install -y httpd
  2. 初始化預設首頁index.html。
    echo "testvm" > /var/www/html/index.html
  3. 啟動HTTP服務。
    service httpd start
  4. 訪問本地的80通信埠,確認Web服務可用。
    curl localhost
  5. 在PTS中建立測試指令碼,開始壓力測試。

    注意關閉長串連和設定逾時時間:

    • 設定逾時時間為5秒: PTS.HttpUtilities.setTimeout(5000)
    • 關閉長串連: PTS.HttpUtilities.setKeepAlive(False)