如何生成每秒百萬級別的 HTTP 請求?


本文是構建可以每秒處理 3 百萬請求的高性能 Web 集羣系列文章的第一篇。它記錄了我使用負載生成器工具的一些經歷,但願它能幫助每個像我同樣不得不使用這些工具的人節省時間。apache

負載生成器是一些生成用於測試的流量的程序。它們能夠向你展現服務器在高負載的狀況下的性能,以及讓你可以找出服務器可能存在的問題。經過負載測試瞭解服務器的缺點,是測試服務器彈性以及未雨綢繆的好方法。vim

負載生成工具(Load-Generating Tools)bash

在進行負責測試時要牢記一件重要的事:你能在 Linux 上創建多少個 socket 鏈接。這個限制是硬編碼在內核裏的,最典型的就是臨時 W 端口的限制。(在某種程度上)你能夠在 /etc/sysctl.conf 裏擴展它。可是基本上,一臺 Linux 機器只能同時打開大約 64,000 個 socket 。所以在負載測試時,咱們不得不經過在單一的鏈接上儘量多地發出請求來充分利用 socket 。 除此以外,咱們還須要不止一臺的機器來產生負載。不然,負載生成器會把可用的 socket 佔用致使不能產生足夠的負載。服務器

我一開始用的是‘ab’,Apache Bench 。它是我所知道的 http 基準測試工具中最簡單、最通用的。而且它是 Apache 附帶的產品,所以它可能已經存在於你的系統中。不幸的是,我在使用它的時候每秒大約只能生成 900 個請求。雖然我見過其餘人使用它每秒能達到 2,000 個請求,但我能夠當即告訴你,‘ab’並不適合咱們的基準測試。網絡

Httperfsession

接着,我嘗試了 ‘httperf’。這個工具更強大,可是它依然相對簡單而且功能有限。要算出每秒生產了多少個請求並非僅傳遞參數那麼簡單。通過個人屢次嘗試,獲取了每秒超過幾百請求的結果。例如:負載均衡

它以每秒 1,000 個的速率建立了 100,000 個會話(session)。每次會話發起 5 次請求,時間間隔爲 2 秒。

1
httperf --hog --server=192.168.122.10 --wsess=100000,5,2 --rate 1000 --timeout 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Total: connections 117557 requests 219121 replies 116697 test -duration 111.423 s
 
Connection rate: 1055.0 conn /s (0.9 ms /conn , <=1022 concurrent connections)
Connection time [ms]: min 0.3 avg 865.9 max 7912.5 median 459.5 stddev 993.1
Connection time [ms]: connect 31.1
Connection length [replies /conn ]: 1.000
 
Request rate: 1966.6 req /s (0.5 ms /req )
Request size [B]: 91.0
 
Reply rate [replies /s ]: min 59.4 avg 1060.3 max 1639.7 stddev 475.2 (22 samples)
Reply time [ms]: response 56.3 transfer 0.0
Reply size [B]: header 267.0 content 18.0 footer 0.0 (total 285.0)
Reply status: 1xx=0 2xx=116697 3xx=0 4xx=0 5xx=0
 
CPU time [s]: user 9.68 system 101.72 (user 8.7% system 91.3% total 100.0%)
Net I /O : 467.5 KB /s (3.8*10^6 bps)

最終,我使用這些設置達到了每秒 6,622 個鏈接:

1
httperf --hog --server 192.168.122.10 --num-conn 100000 --ra 20000 --timeout 5

(總共建立了 100,000 個鏈接,而且以每秒 20,000 個鏈接的固定速率建立)

它還有一些潛在的優點,而且擁有比‘ab‘更多的特性。但它不是我要用在這個項目裏的重量級工具。我須要的是可以支持分佈式多負載測試節點的工具。所以,個人下一個嘗試是:Jmeter。

Apache Jmeter

這是一個功能齊全的 web 應用測試套件,它能夠模擬真實用戶的全部行爲。你可使用 Jmeter 的代理去訪問你的網站,進行點擊、登錄、模仿用戶能夠作的全部行爲。Jemeter 會把這些行爲記錄下來做爲測試用例。而後 Jmeter 會反覆執行這些動做來模擬你想要的用戶數量。儘管配置 Jmeter 比 ‘ab‘ 和 ’httperf‘ 複雜得多,但它是一個頗有趣的工具!

根據個人測試,它每秒能夠產生 14,000 個請求!這絕對是一個好的進展。

我使用了 Googlle Code project 上的一些插件,而且使用它們的「Stepping Threads」和「HTTP RAW」請求,最終每秒大約能夠產生 30,000 個請求!但這已經達到極限了,因此還要尋找另外一個工具。這裏有一個我以前的 Jmeter 配置,但願能夠幫助到其餘人。雖然這個配置離完美相差甚遠,但有時它能夠知足你的要求。

Tsung: 重型的(heavy-duty)、分佈式的、多協議測試工具

它每秒基本能夠產生 40,000 個請求,這絕對是咱們想要的工具。相似於 Jmeter,你能夠把一些行爲記錄下來在測試時運行,而且能夠測試大多數的協議。好比 SSL、HHTP、WebDAV、SOAP、PostgreSQL、MySQL、LDAP 和 Jabber/XMPP。與 Jmeter 不一樣的是,它沒有讓人感到迷茫的 GUI 設置,它僅有一個 XML 配置文件,和一些你選擇的分佈式節點的 SSH 密鑰。它的簡潔和效率對個人吸引力,徹底不亞於它的健壯性和可擴展性。我發現它是一個很強大的工具,在正確的配置下它能夠每秒產生百萬級的 HTTP 請求。

除此以外,Tsung 還能夠在 html 上產生圖表以及輸入你的測試的詳細報告。測試的結果通俗易懂,而且你甚至能夠把這些圖片展現給你的 boss 看!

在這個系列文章的剩餘部分,我還會講解這個工具。如今你能夠繼續瀏覽下面的配置說明,或者直接跳到下一頁。

在 CentOS 6.2 上安裝 Tsung

首先,你要安裝(Erlang 須要的) EPEL 源。所以,在進行下一步以前要把它安裝好。安裝完後,繼續安裝你用來產生負載的每一個節點須要的包。若是你尚未在節點之間創建無密碼 SSH 密鑰(passwordless SSH key),那麼請創建之。

1
yum -y install erlang perl perl-RRD-Simple.noarch perl-Log-Log4perl-RRDs.noarch gnuplot perl-Template-Toolkit firefox

從 Github 或者 Tsung 的官網上下載最新的 Tsung。

1
wget http: //tsung .erlang-projects.org /dist/tsung-1 .4.2. tar .gz

解壓而且編譯。

1
2
3
tar zxfv  tsung-1.4.2. tar .gz
cd tsung-1.4.2
. /configure && make && make install

把示例配置複製到 ~/.tsung 目錄裏。這是 Tsung 的配置文件和日誌文件的存放地方。

1
cp  /usr/share/doc/tsung/examples/http_simple .xml /root/ .tsung /tsung .xml

你能夠根據你的需求去編輯這個配置文件,或者使用個人配置文件。通過大量的嘗試以及失敗後,我目前的配置文件在使用 7 個分佈式節點時能夠每秒產生 5 百萬個 HTTP 請求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<? xml version = "1.0" ?>
<!DOCTYPE tsung SYSTEM "/usr/share/tsung/tsung-1.0.dtd">
< tsung loglevel = "notice" version = "1.0" >
 
< clients >
< client host = "localhost" weight = "1" cpu = "10" maxusers = "40000" >
< ip value = "192.168.122.2" />
</ client >
< client host = "loadnode1" weight = "1" cpu = "9" maxusers = "40000" >
< ip value = "192.168.122.2" />
</ client >
< client host = "loadnode2" weight = "1" maxusers = "40000" cpu = "8" >
< ip value = "192.168.122.3" />
</ client >
< client host = "loadnode3" weight = "1" maxusers = "40000" cpu = "9" >
< ip value = "192.168.122.21" />
</ client >
< client host = "loadnode4" weight = "1" maxusers = "40000" cpu = "9" >
< ip value = "192.168.122.11" />
</ client >
< client host = "loadnode5" weight = "1" maxusers = "40000" cpu = "9" >
< ip value = "192.168.122.12" />
</ client >
< client host = "loadnode6" weight = "1" maxusers = "40000" cpu = "9" >
< ip value = "192.168.122.13" />
</ client >
< client host = "loadnode7" weight = "1" maxusers = "40000" cpu = "9" >
< ip value = "192.168.122.14" />
</ client >
</ clients >
 
< servers >
< server host = "192.168.122.10" port = "80" type = "tcp" />
</ servers >
 
< load >
< arrivalphase phase = "1" duration = "10" unit = "minute" >
< users maxnumber = "15000" arrivalrate = "8" unit = "second" />
</ arrivalphase >
 
< arrivalphase phase = "2" duration = "10" unit = "minute" >
< users maxnumber = "15000" arrivalrate = "8" unit = "second" />
</ arrivalphase >
 
< arrivalphase phase = "3" duration = "30" unit = "minute" >
< users maxnumber = "20000" arrivalrate = "3" unit = "second" />
</ arrivalphase >
 
</ load >
 
< sessions >
< session probability = "100" name = "ab" type = "ts_http" >
< for from = "1" to = "10000000" var = "i" >
< request > < http url = "/test.txt" method = "GET" version = "1.1" /> </ request >
</ for >
</ session >
</ sessions >
</ tsung >

剛開始的時候有不少東西要理解,但你一旦理解了它們後就會變得很簡單。

  • <client> 只是簡單地指定了運行 Tsung 的主機。你能夠指定 Tsung 使用的 IP 和 CPU 的最大數。你可使用 maxusers 設置節點可以模擬的用戶數量上限。每個用戶都會執行咱們以後定義的操做。

  • <servers> 指定了你要測試的 HTTP 服務器。咱們可使用這個選項去測試一個 IP 集羣,或者一個單一的服務器。

  • <load> 定義了咱們的模擬用戶將會在何時「到達」咱們的網站。以及它們達到的有多快。

    •  <arrivalphase> 在持續了 10 分鐘的第一個階段裏,以 每秒 8 個用戶的速率到達了 15,000 個用戶。

    • <arrivalphase phase=」1″ duration=」10″ unit=」minute」>

    • <users maxnumber=」15000″ arrivalrate=」8″ unit=」second」/>

    •  這裏還有兩個 arrivalphases,它們的用戶都以一樣的方式達到。

    •  這些 arrivalphases 一塊兒組成了一個 <load>,它控制了咱們能夠每秒產生多少個請求。

  • <session> 這部分定義了一旦這些用戶達到了你的網站,它們將會執行什麼動做。

  • probability 容許你定義用戶可能會作的隨機事件。有時他們可能點擊這裏,有時他們可能點擊那裏。全部的Probability 加起來必定要等於 100% 。

  • 在上面的配置裏,用戶只作一件事,因此它的 probability 等於 100% 。

  • <for from=」1″ to=」10000000″ var=」i」> 這就是用戶在 100% 的時間裏作的事情。它們循環遍歷 10,000,000 次而且 <request> 一個網頁:/test.txt 。

  • 這個循環結構容許咱們使用少許的用戶鏈接去獲取比較大的每秒請求數量。

一旦你已經很好地理解了它們,你就能夠建立一個便利的別名,去快速觀察 Tsung 報告。

1
2
vim ~/.bashrc
alias treport= "/usr/lib/tsung/bin/tsung_stats.pl; firefox report.html"
1
source ~/.bashrc

而後啓動 Tsung

1
2
3
[root@loadnode1 ~] tsung start
Starting Tsung
"Log directory is: /root/.tsung/log/20120421-1004"

結束後觀察報告

1
2
cd /root/ .tsung /log/20120421-1004
treport

使用 Tsung 去規劃你的集羣構造

如今咱們擁有了一個足夠強大的負載測試工具,咱們能夠規劃餘下的集羣構造了:

1. 使用 Tsung 去測試一個單一的 HTTP 服務器。獲取一個基本的基準。
2. 對 web 服務器進行調優,按期使用 Tsung 進行測試提升性能。
3. 對這些系統的 TCP 套接字進行調優,獲取最佳的網絡性能。再來一次,測試,測試,不停地測試。
4. 構造 LVS 集羣,它包含了這些充分調優過的 web 服務器。
5. 使用 Tsung IP 集羣對 LVS 進行壓力測試。

在以後的兩篇文章裏,我將會向你展現如何使你的 web 服務器獲取最高性能,以及怎樣用 LVS 集羣軟件把它們整合起來。


備註: 其它的參考文檔 http://langzhe.iteye.com/blog/773919

相關文章
相關標籤/搜索