文章導讀
服務壓力測試,是評估一個服務是否優秀的過程,他不只能讓你找到你的服務哪些地方存在性能瓶頸,並且還能讓你準確的去作容量評估,防止容量不足,也規避了資源浪費。本文會帶你瞭解如下幾點內容:php
-
壓測的意義 -
壓測注意點 -
壓測準備 -
模型壓測的自我理解 -
普通壓測工具 -
goreplay壓測工具介紹
爲何要壓測
-
業務推廣保障 -
準確評估容量 -
快速發現服務瓶頸 -
極限壓力測試 -
服務遷移全鏈路測試
壓測須要注意哪些點(重點閱讀)
-
環境統一(基礎環境、參數配置、資源型號、請求鏈路) -
壓測機不能存在瓶頸 -
壓測姿式一致 -
屢次壓測 -
注意 寫
流量(若是你不想產生髒數據) -
注意三方依賴服務(你壓測A服務,要考慮是否會順帶壓測到B服務) -
極限壓測過程當中注意拐點(某些時候你qps上不去,響應時間大幅度上漲,那就說明是拐點了)
環境統一
這個目前咱們有兩種方式,第一種是新建測試環境壓測,第二種是直接在生產環境壓測。若是新建,那麼咱們須要考慮的點就是跟生產環境徹底一致。nginx
-
基礎環境,包括系統版本,系統參數配置 -
軟件環境,好比 Php 版本,Php 參數配置 -
資源型號,機器的型號配置,Redis 的規格,MySql 的規格等 -
請求鏈路,好比我請求的鏈路是通過兩層 Nginx,不能在壓測的時候只通過一層 Nginx。
壓測機器不能存在瓶頸
咱們以前在壓測過程當中,會發現當壓測到必定量級後就上不去了,這時候咱們一直在排查服務端是否有什麼問題,包括部署資源是否足夠,後端資源是否性能瓶頸,帶寬是否打滿等信息,繞了一圈都沒有發現問題。最終咱們發現是壓測端機器性能較低,帶寬打滿了,最終換用了更高配的機器來進行壓測。因此咱們壓測端必定不能成爲壓測計劃的瓶頸。git
壓測姿式一致
簡單舉個例子,用ab壓測的時候,須要指定線程,壓測時間等參數,假如第一次用10個線程,壓測10分鐘,第二次用12個線程,壓測20分鐘github
那麼這樣獲得的數據是徹底無用的。web
屢次壓測
性能壓測的數據是屢次得來的,結論也是屢次數據對比得出的。因爲每次壓測都會有沒法預知的問題,因此每次壓測結束後,都須要分析結果,看看是否符合預期,好比在第二次壓測,某截網絡斷了,那麼獲得的數據可能會很是差,那麼此次的壓測數據就不能使用。shell
注意寫
流量
這個也是跟咱們的壓測場景有關。json
-
當咱們在生產壓測,那麼咱們確定不能有寫流量的壓測,那麼咱們的生產數據就會髒掉,除非這些數據可以把控,在壓測後能徹底刪除,否則是隻能壓測讀流量。 -
當咱們在測試環境壓測,這種狀況能夠壓測全鏈路,不過有一個點須要關注下,當咱們是服務遷移的壓測,這時候生產環境跟測試環境是數據實時同步的,測試環境的髒數據也會回寫到生產環境。
注意三方依賴服務
再舉個例子,我美顏相機服務要準備壓測,依賴登陸、素材展現兩個服務。後端
那麼咱們在壓測的時候必定要去周知登陸和素材的開發同窗,以及讓他們作好擴容準備和實時監控,實時反饋目前的一個服務狀態,當有異常的時候,應當即中止壓測。微信
極限壓測過程當中注意拐點
在咱們壓測過程當中,是須要記錄每次壓測的結果的,好比壓測結果的qps、相應時間、服務SLA等信息。當某些值在必定持續增加的壓力下增加緩慢、不增加甚至下降,那麼這時候你就要考慮壓測是否到達了必定的拐點,相似能夠作一個以下的圖來簡單判斷拐點:網絡
壓測前準備
-
明確總體系統鏈路狀況 -
依賴資源的容量評估,確認壓測的時候是否須要擴容 -
壓測部分降級方案的確認
明確總體系統鏈路狀況
業務壓測前,首先須要明確業務架構,開發須要配合運維梳理整個系統結構,開發補充業務層面,運維補充系統層面,整理出一個流量走勢以及三方依賴圖。明確是否跨機房、是否跨專線、是否存在網絡隔離等問題。
依賴資源的容量評估
例子,A業務壓測,三方依賴服務有B和C,首先要記錄當前生產業務的qps,B和C業務的使用量級。假如是1000qps,B用量10臺機器,C用量20臺機器。那麼咱們壓測須要壓到2000qps,理論上B用20臺機器,C用40臺機器。
壓測部分降級方案的確認
作壓測工做,咱們須要明確幾點:
-
咱們是爲了保障線上業務穩定才作的壓測,全部的評估都要有預留。 -
壓測遇到的問題也正是咱們上生產或者遷移後遇到的問題,因此每個問題都須要正視。
因此針對上面兩點,咱們須要明確業務容量評估必定要留cache,降級方案、回退方案必定要有,防止真的出現問題。下面是咱們在壓測過程當中遇到的問題以及處理的過程:
模型壓測(自我理解)
這是我在壓測過程當中,總結的一個點,這個我可能無法用很好的詞語來描述,我就用一個簡單的例子來描述吧。
業務場景:簡單的 Nginx + PHP 業務,容器化部署。
那麼咱們能夠配置如下幾個壓測模型場景來進行壓測,而後給出相應的結論:
-
單 Pod CPU 內存壓測 -
單 Pod Nginx + PHP 空接口壓測 -
單 Pod Nginx + PHP 業務單接口壓測
-
關於單 Pod CPU 內存壓測,咱們能夠在業務部署機器上啓動一個空 Pod,而後進行壓測,不涉及任何業務,這裏獲得的結論 --- 排除底層平臺帶來的影響。 -
單 Pod Nginx + PHP 空接口壓測,這裏你能夠隨便寫一個php接口,return 一個 OK 就行,而後進行壓測,這裏獲得的結論 --- 排除業務基礎環境帶來的影響好比 Nginx + PHP 等。 -
單 Pod Nginx + PHP 業務單接口壓測,這裏找一個具備表明性的接口,什麼是具備表明性的接口,好比這個接口是涉及到讀 Redis 或者 MySql 等後端資源的。這裏獲得的結論 --- 業務層面的一個壓測結果。
通過這一輪壓測以後,你能很是明確你的壓測結論是否存在異議,一步步排除環境因素。
普通壓測工具介紹
目前來講,我在運維過程當中使用的壓測工具也就是ab,wrk等,其實針對不一樣的場景,每個工具都有本身的優勢和缺點。
ab
-
支持多平臺 -
默認短連接 -
只能單進程 -
沒法控制壓測時間,控制速率
wrk
-
類unix -
支持多線程(更容易發揮多核的能力) -
支持自定義腳本 -
默認長連接
goreploay介紹
優勢
-
可用於服務遷移前的全鏈路測試 -
支持http請求錄製和重放,能夠複製線上請求,在壓測環境重放 -
支持http層的流量過濾,好比我只複製某一個接口的請求 -
支持請求放大,用於性能壓測 -
......
文檔地址
官方git地址:https://github.com/buger/goreplay官方文檔:https://github.com/buger/goreplay/wiki
流量捕獲
-
input-raw 捕獲 HTTP 流量,需指定端口號 -
input-file 使用 –output-file 記錄的文件做爲輸入 -
input-tcp 將多個 Gor 實例獲取的流量彙集到一個 Gor 實例
流量重放
-
output-http 將流量重放到URL地址 -
output-file 將獲取的流量記錄如文件 -
output-tcp 將獲取的流量轉移至另外的 Gor 實例,與input-tcp組合使用 -
output-stdout debug 工具,將流量信息直接輸出
請求過濾
-
http-allow-url 只發送正則匹配的url的請求 -
http-disallow-url 不發送正則匹配url的請求 -
http-allow-header 只發送指定head的請求 -
http-disallow-header 不發送指定head的請求 -
http-allow-method 容許的請求方法 -
http-set-header 增長http-header
流量限制
-
隨機丟棄一部分請求 -
按照準確的qps限制 -
按照比例限制(這裏的比例,能夠實現大於100%,即倍量的壓測) -
根據Header 或者 URL 參數限制一部分請求
實戰演練
goreplay安裝
依賴go環境wget https://github.com/buger/goreplay/releases/download/v1.0.0/gor_1.0.0_x64.tar.gztar xvf gor_1.0.0_x64.tar.gz
抓取流量
在公司中,咱們的流量入口通常是公共代理,好比nginx等。下面例子是我在公司其中一臺公共代理上抓取的流量,有如下幾個說明:(給的例子是我在使用過程當中的,有特殊需求的能夠參考官方文檔進行相應的修改)
-
80端口 -
allow header:lb6test.meitu.com,這就是我想要壓測的服務域名 -
method是get,由於post請求咱們不壓測,涉及到寫數據 -
allowurl是我只想要抓取這個域名中a和b這兩個接口的流量 -
disallow header,我要抓取token爲空的,由於不爲空的token涉及到登陸,會連帶壓測咱們登陸的服務 -
outputfile:把抓取的流量輸出爲一個流量包,這樣好攜帶
./goreplay --input-raw :80 --http-allow-header 'Host: lb6test.meitu.com' -http-allow-method 'GET' -http-allow-url '/a/a.json' -http-allow-url '/b/b.json' -http-disallow-header 'Access-Token:' -output-file meitu.gor
普通輸出流量
這個操做通常咱們會放到單獨的壓測機器上進行,若是你壓測的是新部署的測試環境,注意這個域名必定要在這個機器上綁定一個host,防止你壓測到生產環境去了。
-
loop,循環壓測,由於流量包抓取的時間是固定的,若是不循環壓測,流量重放結束就會終止壓測 -
disallowurl,我忽然不想壓測b接口的流量,那麼就關閉掉。 -
outputhttp,從該壓測機發起對測試環境的請求流量
./goreplay --input-file-loop --input-file "meitu.gor" --http-disallow-url "/b/b.json" --output-http "http://lb6test.meitu.com"
壓測輸出流量
當你按照普通輸出流量走一遍的時候,而且不過濾任何接口,你就會知道你這個流量包到底有多少流量,是多少 qps,假如個人meitu.gor
是100 qps。
我想要50qps
./goreplay --input-file-loop --input-file "meitu.gor" --output-http "http://lb6test.meitu.com|50"
我想要200qps
這裏一個操做是把流量放到1000%,那麼你就能夠認爲這個qps是無限大的,你能夠任意指定你想要的qps了。
./goreplay --input-file-loop --input-file "meitu.gor|1000%" --output-http "http://lb6test.meitu.com|200"
一次壓測太慢,我要快速壓測
若是你以爲一個進程太慢了,那麼就多啓動幾個進程進行壓測吧
nohup ./goreplay --input-file-loop --input-file "meitu.gor" --output-http "http://lb6test.meitu.com" > /dev/null 2>&1
輸出文檔
咱們壓測好以後,應該輸出哪些東西呢
-
基礎壓測的數據 -
極限壓測的數據 -
不一樣壓力下的數據 -
qps,響應時間,成功率
下面是我當時壓測公司某個服務記錄的一些信息和描繪的圖。
本文分享自微信公衆號 - 程序猿的野生香蕉(gh_2e510bc5c532)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。