《我們如何使用HAProxy實現單機200萬SSL連接》要點:
本文介紹了我們如何使用HAProxy實現單機200萬SSL連接,希望對您有用。如果有疑問,可以聯系我們。
導讀:架構師需要精確的了解服務的支撐能力,也希望通過調優來發揮單個節點最大的價值.本文分享了壓測及調優 HAProxy 實現 200 萬并發 SSL 連接的過程,由高可用架構翻譯,轉載請注明出處.
先觀察上面截圖,可以看到兩個關鍵信息:
下面將會介紹在單個 HAProxy 機器上實現這種規模訪問所需的配置.本文是負載測試 HAProxy 系列文章的最后一篇.有時間的讀者建議閱讀本系列的前兩篇(見文末鏈接),它將幫助您了解相應的內核調優方法.
在這個配置過程中,我們也使用了很多小組件幫助我們達到目標.
在展開最終 HAProxy 配置之前,我想給大家回顧一下負載測試的歷程及想法,心急的讀者可以直接跳到文章后段查閱相關 HAProxy 配置.
我們要測試的組件是 HAProxy 1.6 版.生產環境是在 4 核 30 G 的機器上運行該軟件,當前所有的連接都是非 SSL 的.
測試目標有兩方面:
目標一主要因為業務方面功能需要通過 SSL 進行通信. 目標二是為了可以在生產環境中部署最少規模的 HAProxy 機器.
HTTP 和 MQTT
我們的整個基礎設施支持兩種協議:
在我們的技術棧中,沒有使用 HTTP 2.0,因此在 HTTP 上沒有長連的功能.所以在生產環境中,單個 HAProxy 機器(上行 + 下行)的最大數量的 TCP 連接在(2 * 150k)左右.雖然并發連接數量相當低,但每秒請求的數量卻相當高.
另一方面,MQTT 是一種不同的通信方式.它提供高質量的服務參數和持久的連接性.因此,可以在 MQTT 通道上使用雙向長連通信.對于支持 MQTT(底層 TCP)連接的 HAProxy,在高峰時段會看到每臺機器上大約有 600 – 700k 個 TCP 連接.
我們希望進行負載測試,這將為我們提供基于 HTTP 和 MQTT 連接的精確結果.
有很多工具可以幫助我們輕松地測試 HTTP 服務器,并且提供了高級功能,如結果匯總,將文本轉換為圖形等.然而,針對 MQTT,我們找不到任何壓力測試工具.我們確實有一個自己開發的工具,但是它不夠穩定,不足以支持這種負載.
所以我們決定使用客戶端測試 HTTP 負載,并在 MQTT 服務器使用相同配置.
考慮到相關內容對于進行類似的壓力測試或調優的人來說有幫助,本文提供了很多相關細節,篇幅稍微有些長.
ab 工具提供了許多有用的參數用于我們的負載測試,如:
如果仔細觀察這些參數,您會發現通過調整所有這三個參數可以進行很多排列組合.示例 ab 請求將看起來像這樣
ab -S -p post_smaller.txt -T application/json -q -n 100000 -c 3000
http://test.haproxy.in:80/ping
這樣的請求的示例結果看起來像這樣
我們感興趣的數字是:
ab 的最大問題是它不提供控制每秒發起請求量,因此我們不得不調整 -c 并發級別以獲得所需的每秒鐘請求數,并導致很多后文提到的問題和錯誤.
我們不能隨機地進行多次測試來獲得結果,這不會給我們提供任何有意義的信息.我們必須以某種具體的方式執行這些測試,以便從中獲得有意義的結果.來看看這個圖.
該圖表明,在某一點之前,如果不斷增加請求數量,延遲將幾乎保持不變.然而,達到某個臨界點,延遲將開始呈指數級增長.這就是該機器的臨界點.
Ganglia
在提供一些測試結果之前,我想提一下 Ganglia.
Ganglia 是用于高性能計算系統(如集群和網格)的可擴展分布式監控系統.
看看截圖,了解 Ganglia 是什么,以及它提供的關于底層機器的信息.
通過 Ganglia 可以監測 HAProxy 機器上一些重要參數.
以下是通過通過負載測試找到的已知限制.
700k TCP 連接,
50k 發送包數量,60k 接收包數量,
10-15MB 發送及接收的字節數,
14-15G 內存峰值,
7MB 帶寬.
所有這些值都是基于每秒數據
HAProxy Nbproc
最初,當我們開始測試 HAProxy 時,發現使用 SSL 情況下,CPU 很早就到了瓶頸,而每秒請求數都很低. 在使用 top 命令后,發現 HAProxy 只使用 1 個 CPU 核. 而我們還有 15 個以上的核沒用.
Google 了 10 分鐘后,我們在 HAProxy 中找到某個設置,可以讓 HAProxy 使用多個核.
它被稱為 nbproc,具體設置請看這篇文章 [8]:
調整此設置是我們的負載測試策略的基礎. ?讓我們可以方面的進行 HAProxy 組合以便測試.
當開始負載測試之旅時,我們不清楚應該測量的指標和需要達到的目標.
最初,我們只有一個目標:通過改變所有下面提到的參數來找到臨界點.
我保留了各種負載測試結果的表格. 總而言之,做了 500 多次測試,以達到最終的效果. 您可以清楚地看到,每次測試都有很多不同的部分.
我們看到客戶端正在成為瓶頸,因為我們不斷增加每秒的請求數. ab 使用單個核,從文檔中可以看出,它不提供使用多核的功能.
為了有效地運行多個客戶端,我們發現一個有用的 Linux 工具叫做 Parallel [7]. 顧名思義,它可以幫助您同時運行多個命令來達到并行的目的. 正是我們想要的.
看一下使用 Parallel 運行多個客戶端的示例命令.
上述命令將運行 3 個 ab 客戶端擊訪問同一個 URL. 這有助于我們消除客戶端瓶頸.
下面是 Ganglia 中的一些參數.讓我們簡單討論一下.
我們在 POST 調用中加入了一個 sleep 參數,它指定了服務端發送返回之前需要 sleep 的毫秒數.這將模擬長時間運行的生產環境請求.如果讓請求 sleep 20 分鐘的話,只需要每秒發出 583 個請求就能達到 700k 并發連接的標準.
此外,我們還在 POST 調用中引入了另一個參數: times.服務器在返回請求時應該在 TCP 連接上寫入響應的指定次數,這有助于模擬更多的數據.
雖然使用 AB 也得到了不少測試結果,但同時也遇到了很多問題.我不會在這里提到所有問題,因為不是這篇文章重點(下面介紹另一個客戶端).
我們非常滿意從 ab 上獲得的結果,但是它不支持在一段時間內生成所需指定的 TCP 連接數.不知何故,我們設置的 sleep 參數在 ab 上無法生效.
雖然在一臺機器上可以運行多個 ab 客戶端并且可以用工具合并結果,但是在多臺客戶機上運行此設置對我們來說仍然是一件痛苦的事情.那時我還沒有聽說過 pdsh [4] 這個工具.
此外,我們也沒有關注過超時的問題.在 HAProxy,ab 客戶端和服務器上有一些默認的超時設置,我們完全忽略了這些.后文會講到.
我們一開始就提到通過臨界點圖來檢測系統的上限,但講了這么多有點偏離了最主要目標.然而,要得到有意義的結果只能著眼于這一點.
使用 AB 碰到的一個問題是到了某個點 TCP 連接數不再增加.我們有大約 40 – 45 個客戶端運行在 5 – 6 臺客戶端機上,但依然不能達到想要的規模.理論上,TCP 連接的數量應該隨著 sleep 時間的增加而增加,但對我們來說并非如此.
因此我們需要尋找一個負載測試工具,這些工具需要具有更好的擴展性和更好的功能性,最終,我們找到了 Vegeta [6].
從我的個人經驗來看,我已經看到 Vegeta 具有極高的擴展性,與 ab 相比,它提供了更好的功能. 在我們的負載測試中,單個 Vegeta 客戶端能夠產生相當于 15 倍 ab 的吞吐量.
下面,我將提供使用 Vegeta 的負載測試結果.
首先,看看我們用來運行一個 Vegeta 客戶端的命令. 進行測試的命令稱為 attack:(酷吧?)
我們太喜歡 Vegeta 提供的參數了,來看看下面的一些參數.
所以如上圖所示,我們在一臺 4 核機器上每秒達到了 32k 請求量. 如果你記得臨界點圖,在這種情況下,非 SSL 請求的臨時點是 31.5k.
從負載測試中看更多的結果.
16k 的 SSL 連接也不錯. 請注意,在我們的負載測試過程中,必須從頭開始,因為我們采用了一個新的客戶端,它給了我們比 ab 更好的結果. 所以不得不再來一遍.
CPU 核數的增加導致機器在未達到 CPU 限制前,每秒可以用的請求數增加.
如果將 CPU 核數從 8 個增加到 16 個,我們發現每秒的請求數量并沒有大幅度增加.如果在生產環境中使用 8 核機器,那么我們不會分配所有的核給 HAProxy,或者是它的任何其他進程. 所以我們決定用 6 核機器進行一些測試,看看是否能得到可接受的數字.
結果還不錯.
我們現在對負載測試結果非常滿意. 然而,這并沒有模擬真正的生產場景. 當我們引入 sleep,才開始模擬生產環境的情況.
echo “POST https://test.haproxy.in:443/ping” | vegeta -cpus=32 attack -duration=10m ?-header=”sleep:1000″ ?-body=post_smaller.txt-rate=2000 -workers=500 ?| tee reports.bin | vegeta report
因此,x 毫秒的隨機 sleep 時間將導致服務器 sleep 時間為 0 < x < 1000 . 因此上述負載測試將給出平均?≥ 500ms 的延遲.
最后一個單元格中的含義是 TCP established, Packets Rec, Packets Sent
從表中可以看到,6 核機器可以支持的最大請求量從 20k 減少到 8k. 顯然,sleep 有其影響,影響的是 TCP 連接的數量. 然而這距離我們設定的 700K 目標還很遠.
里程碑 #1
我們如何增加 TCP 連接的數量? 很簡單,不斷增大 sleep 時間,連接數應該上升. 我們一直增加 sleep 時間并在 60 秒的 sleep 時間停了下來. 這意味著大約 30 秒的平均延遲.
Vegeta 可以提供成功請求百分比的結果參數. 我們看到,在上述的 sleep 時間,只有 50% 的調用是成功的. 請看下面的結果.
我們達到了 400 萬個 TCP 連接,在每秒 8k 請求和 60s 的 sleep 時間的情況下. 60000R 的 R 表示隨機.
我們的第一個的發現是,在 Vegeta 中有一個默認的超時時間是 30 秒,這就解釋了為什么 50% 的請求會失敗. 所以我們在后續測試中將超時調整到 70 秒,并隨著需求的變化而不斷變化.
在客戶端調整超時值之后,我們可以輕松地達到 700k 標準. 唯一的問題是這些不可持續,只是峰值的數據. 系統達到了 600k 或 700k 的峰值鏈接,但并沒有堅持很長時間.
但是我們想要得到圖上連接持續很久的效果
這顯示了穩定保持 780k 連接的狀態.如果仔細查看上面的統計信息,每秒的請求數量非常多.然而,在生產環境中,我們在單個 ?HAProxy 機器上的請求數量要少得多(約 300 個).
我們確信,如果減少生產環境的 HAProxy 的數量(約 30 個,這意味著每秒 30 * 300?9k 的連接),我們將會達到機器 TCP 連接限制,而不是 CPU.
所以我們決定實現每秒 900 個請求、30MB/s 的網絡流量,以及 210 萬 TCP 連接.我們選用這些數字,因為這將是單個生產環境 HAProxy 機器的 3 倍流量.
到目前為止,我們已經配置了 HAProxy 使用 6 核.我們只想測試 3 核,因為這是我們在我們的生產機器上使用的最簡單的方法(如前所述,我們的生產機器是 4 核 30G,所以用 nbproc = 3 進行更改將是最簡單的).
里程碑 #2
現在我們對每秒請求的最大限制可以隨機器不同而變化,所以我們只剩下一個任務,如上所述,實現 3 倍的生產負載:
在 220k 的測試環境下,我們再次陷入僵局. 無論客戶機數量多少或睡眠時間多少,TCP 連接數似乎都停留在那里.
我們來看一些估算數據. 220k TCP 連接,每秒 900 個請求 = 110,000 / 900?= 120 秒.達到了 110k,因為 220k 連接包括上行和下行.
當我們在 HAProxy 開啟日志時,我們懷疑 2 分鐘是系統某處的限制. 我們可以看到 120,000 ms 是日志中大量連接的總時間.
在進一步調查中,我們發現 NodeJs 的默認請求超時為 2 分鐘. 瞧!
但我們的高興顯然很短暫,在 130 萬,HAProxy 連接數突然下降到 0,并再次開始增長.我們很快檢查了 dmesg 命令,里面可以查到 HAProxy 進程一些有用的內核信息.
基本上,HAProxy 進程已經耗盡內存.因此,我們決定增加機器內存,并將其轉移到 nbproc = 3 的 16 核 64GB 的機器,經過調整,我們終于可以達到 240 萬長連.
下面是正在使用的后端服務器代碼. 我們還在服務器代碼中使用 statsd 來獲取客戶端接收的每秒請求的統計數據.
我們還有一個小腳本運行多個服務器. 我們有 8 臺機器,每臺機器部署了 10 個后端服務. 我們真的認為有條件的話可以進行無限擴容進行壓測.
對于客戶端,每個 IP 有最大 63k TCP 連接的限制. 如果您不確定這個概念,請參閱本系列之前的文章.
所以為了實現 240 萬個連接(雙向,來自客戶機的是 120 萬),我們需要約 20 臺機器. 我們在所有機器上運行 Vegeta 命令,甚至找到了一種方法來使用像 csshx [3] 這樣的工具,但仍然需要合并所有的 Vegeta 客戶端的結果.
查看下面的腳本.
Vegeta 提供了名為 pdsh [4] 的工具信息,可讓您在多臺計算機上同時運行命令. 此外,Vegeta 可以讓我們將多個結果合并成一個,這就是我們想要的.
下面可能是很多讀者最關心的,我們在測試中使用的 HAProxy 配置. 最重要的部分是 nbproc 和 maxconn 參數. maxconn 設置 HAProxy 允許提供的最大 TCP 連接數(單向).
對 maxconn 設置的更改導致 HAProxy 進程的 ulimit 增加. 看看下面
最大打開文件已增加到 400 萬,因為 HAProxy 的最大連接數設置為 200 萬.
參閱文章 [5] 獲得更多 HAProxy 優化.
相關鏈接
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4215.html