您好,登錄后才能下訂單哦!
?
作者:大開科技-曹向志
摘要:本次測試是受甲方公司委托,對運用區塊鏈技術的一個應用后臺系統進行負載測試,主要是評估系統在系統資源正常利用率下TPS是否能夠達到20000,并發用戶超過2000,響應時間不超過0.2秒。測試環境搭建全部基于云上,可以根據需要擴展應用服務器和壓力機。建立在區塊鏈技術上的應用系統特點是部署在Docker里,且只能通過后臺服務接口調用,部署在Tomcat之上,Berkeley DB內存數據庫的key-value形式,是一個之前未曾測試過的一種部署。之前聽同行說過,云上服務器不好監控,這次又是在Docker里面,是否可以監控呢?等著我們的是否是一次挑戰呢?
前言:
當前,各行各業都在研究區塊鏈技術的運用,區塊鏈技術依據其自身所具備特性可部分或全部運用到某些業務領域,推動該業務領域的創新,例如:銀行、保險、游戲、電商等以及有實力的軟件服務集成商都投入團隊研究區塊鏈技術。其中虛擬貨幣可能是最適合區塊鏈技術運用的方向之一。我們有幸負責該領域一個軟件系統的性能測試,接觸到該業務領域。實屬幸運!
系統背景:
區塊鏈解決的是不可信網絡下的分布式共識計算方案。區塊鏈的效率以及規模,取決于核心共識算法。包括合法性、完整性、可終止性三個重要屬性。從最早的拜占庭將軍問題,引出一種容錯理論。隨后1985年 Fischer和Lynch發表了FLP不可能性定論和1998年Eric Brewer的CAP的三角理論法,給異步網絡下共識模型提供了很好的理論基礎。
在共識算法理論基礎下,有很多實現的計算機算法,例如Paxos、Raft、PBFT等。PBFT提出了實際的解決方案,系統通過訪問控制來限制失效客戶端可能造成的破壞,審核客戶端并阻止客戶端發起無權執行的操作。同時,服務可以提供操作來改變一個客戶端的訪問權限。因為算法保證了權限撤銷操作可以被所有客戶端觀察到,這種方法可以提供強大的機制從失效的客戶端×××中恢復。
BTC比特幣采用挖礦記賬方式,即工作量證明(PoW)來解決BFT的問題。由礦工用計算機算力來解密碼學題目的方式爭奪記賬權利,并且給予勝利者一定比特幣的獎勵。工作量證明機制完全依靠經濟激勵的方式來大量增加記賬參與者,從而稀釋作惡節點的比例,或者說大幅增加作惡的成本,做假賬者需要控制或者賄賂更多的節點。現在體量最大的兩條交易區塊鏈,比特幣和以太坊ETH都是用PoW挖礦的方式。
共識的性能決定了給鏈的節點間視圖數據信息一致性效率。而同步的視圖的數據,需要提供更大的存儲空間,才能為整個鏈提高區塊的批量效率。
系統性能測試需求:
該系統主要運用了區塊的形成機制,在多個節點上達成共識。通過基本賬戶轉賬交易、智能合約轉賬、隨機合約調用轉賬三種機制,在多個節點上形成共識。
該系統的性能指標要求:
1、 并發用戶2000
2、 TPS 2萬/秒
3、 平均響應時間0.2s
4、 10個節點資源監控正常
5、 事務成功率達到100%
測試類型:單交易基準測試、單交易負載測試、混合業務負載測試,如果有時間,進行穩定性測試
客戶提供的測試環境:
應用服務器軟硬件環境:阿里云 Intel(R) Xeon(R) Gold 6148 CPU 2.4GHz,16CPU、16G;軟件:操作系統CentOS 7.0,內存數據庫
壓力機軟硬件環境:阿里云Inter(R) Xeon(R)Gold 614、8 CPU; CPU:Inter(R) Pentium(R) CPU G2030,2.40GHZ,8CPU內存16G;操作系統:Windows server 2012
測試環境拓撲圖如下:
性能測試需求分析:
該系統主要對并發用戶數、響應時間、TPS、事務正確率有比較高的要求,各應用節點資源要求使用率不高于80%,對于Linux(CentOS)平臺來說,應該控制在65%利用率左右。由于該應用特點是采用節點擴展方式,所以測試的重點是通過執行測試,找到服務器的處理能力,為后續的上線做一個服務器選擇的參考。
測試設計:
系統要求測試類型,單交易基準測試、單交易負載測試、混合交易負載測試。主要是確定典型交易,通過溝通,確定典型交易共有6個,基本賬戶轉賬、智能合約轉賬、隨機合約調用、交易查驗、區塊查驗和賬戶查驗。每個交易所占比例基本相同。被測試系統使用Tomcat部署,整個應用部署在docker里,每臺服務器也可以部署多個Docker,在測試里,沒有贊成這樣部署。
對于應用服務器的監控,考慮可以通過Loadrunner結合vmstat、top等命令行工作監控,對于JVM考慮是否可以通過jvisulevm監控。實際上無法監控。JDK版本為1.7。還是原來的內存分配和回收策略。還沒有升級到1.8,采用元空間的方式。對于JDK,最后方案選擇使用jstat在Docker里進行監控。
對于使用多少臺應用服務器和壓力機能夠達到要求的性能指標,無法評估,只能通過在測試幾個場景后,才能評估獲得。
壓力機盡量采用低版本的Windows server版本,因為是云上服務器,只提供服務器版本。對于高版本的Windows sever有可能在測試過程中遇到未曾遇到的新問題。
風險考慮:
由于性能測試團隊第一次在基于云上的測試環境進行測試,可能會遇到資源監控、應用服務器和壓力機等環境上的各種問題。
監控的服務器節點比較多,一臺Controller是否可以做到,需要在測試過程中評估。
對于測試過程中腳本和參數化數據,是否容易構造,且能夠高效率的構造,否則會消耗太多的時間構造測試用數據。
典型交易腳本編寫:
由于上述6個交易類型全部為后臺交易,需要游戲前端調用產生交易,是無法錄制腳本再增強腳本的。設計有兩種方案,第一種方案是編寫調用后臺方法,這樣需要開發提供交易接口,還需要提供鑒權方法,以及hash產生方法。第二種方案是由開發封裝6個交易方法,只是提供測試調用接口即可。最后通過商議,開發決定采用第二種方案。這可能是開發覺得比較安全的方式。:)
基本賬戶轉賬的訪問代碼如下:
web_set_max_html_param_len("300000");
lr_start_transaction("基本賬戶轉賬300");
web_reg_save_param("txhash2","LB=\"txhash\": \"", "RB=\",\"from\"", LAST );
web_url("ta300.icwv1.co",
"URL=http://192.168.1.12:端口號/tst/pbte.do/",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Snapshot=t1.inf",
"Mode=HTML",
LAST );
lr_end_transaction("基本賬戶轉賬300", LR_AUTO);
//格式化的往文件fp1中寫字符串
if(strlen(lr_eval_string("{txhash2}"))==64)
fprintf( fp1,"%s\n",lr_eval_string("{txhash2}") );
else
fprintf( fp20,"%s\n",lr_eval_string("{txhash2}") );
?
上面代碼是運用到每一個節點。代碼中主要通過注冊函數獲得訪問基本交易轉賬返回的hash值,把值保存在文件中。該值用例作為基本交易查驗的hash值參數傳入。每個節點劃分為一個事務。單獨統計事務各相關性能指標。
腳本處理上沒有技術障礙,主要是請求中支持json報文格式,壓力機寫本地文件,使用了每個交易寫一個文件,減少文件增大時,寫入的速度。且在每個壓力機上分別創建目錄和空間記錄返回值。
在場景設置中,由于并發量比較大,在加壓過程、減壓過程中注意根據前面的試運用過程,掌握每個虛擬用戶的初始化時間,減壓時間等,使產生的監控曲線更方便度量和處理。
測試執行過程:
單交易基準測試,主要是1個虛擬用戶迭代10次獲得各種性能指標,主要是查看響應時間,其它指標一般都不會超過指標要求。通過對6個典型交易的基準測試,調試好腳本。測試表名,所有指標都OK。
單交易負載測試,主要是單獨對每一個交易做2000并發用戶測試。為了節省測試時間,沒有采用每次執行并發用戶遞增方式,而是直接使用2000個并發執行測試。監控JVM、服務器的資源使用情況。單交易負載測試,尤其是基本交易轉賬交易,先后執行多次,通過該交易評估出每分鐘需要的hash數,以便后面測試場景設計的執行時間來估算構造數據量。也通過該交易,評估出達到2000個并發需要的應用服務器數量和壓力機數量。解決資源監控和記錄返回報文的解析出hash值的左右邊界以及寫文件方案等。
混合業務負責測試,6個典型交易采用按照等比例的方式,直接使用2000個并發用戶進行負載測試,在測試執行過程中,出現并發虛擬用戶無法加載,最多加載達到1669個并發用戶。監控JVM、服務器的資源使用情況。
整個測試執行過程,有效的測試場景共14個,6個基準,6個單交易,2個混合。
在測試過程中,發現的系統問題主要有:
1、TPS呈現多個波峰現象,處理不穩定。
通過與加載的虛擬用戶數量,處理tps以及服務器資源情況判斷,主要是通過監控JVM垃圾回收情況判斷得出,每隔10秒左右的垃圾回收正好與生成的tps曲線基本一致。初步分析,JVM年老代一直占滿,而年輕代每隔20秒左右滿,這樣導致年輕代觸發垃圾回收,在垃圾回收的幾秒內,tps降低到幾乎為零。為什么在運行初期,年老代會被占滿呢?這與在構造測試數據時可能有關系,每次測試執行之前構造上百萬的測試數據,這些數據構造過程中,占滿了年老代,這可能與開發團隊采用的構造數據代碼使用堆內存方式有關系。解決方案是每次構造數據后,重新啟動服務器,這樣構造的測試數據在文件里,而不是直接在內存里,在-Xms和Xmx參數設定中,都是設定的可使用4G內存。這樣解決了該問題,由于生產中,不用在開始時,構造上百萬的測試數據,不會造成很短時間內進行垃圾內存回收。
2、在混合業務時,后臺日志中拋出并發超時錯誤。
在混合業務2000個并發測試執行中,前臺觀察到的大約200多個虛擬用戶由于失敗等原因停止。開發人員監控后臺日志,發現拋出了大約20個左右的并發超時異常信息。該問題,在測試之前階段,測試和開發人員無法分析出問題原因,2000個并發用戶,分布到10個服務器節點,每個服務器承擔了約200個并發用戶,理論上對于16CPU16G內存的服務器來說,應該能夠承受。具體原因,需要架構師進行深入分析。
在部署10臺服務器節點,使用6臺壓力機和1臺Controller進行壓力測試情況下,無法達到2000個并發,但是TPS能達到20000的要求,響應時間不管是在單交易并發還是混合交易并發情況下,都不超過0.2秒的響應時間。交易成功率雖然無法達到100%,但是超過了99.99%,有少量的失敗或停止。增加服務器節點和壓力機應該可以達到性能要求指標。由于該系統是通過添加服務器節點來支持更多的并發用戶數量,但是有不是線性關系,畢竟每增加一個節點,其在合約判定上都會增加時間消耗。
測試過程問題:
在測試過程中,曾經出現的問題和解決方案如下:
1、壓力機問題,在開始時,單業務2000個并發用戶時,會出現虛擬用戶加載時間過長,或用戶中間由于錯誤、超時等原因停止。采取的措施是增加壓力機的方法,由3臺壓力機增加到6臺,這樣controller不再兼做壓力機了,對于服務器性能指標監控就更及時一些。
2、監控CentOS時,沒有安裝RPC服務。通過下面方法安裝RPC服務,安裝后,啟動3個服務解決。
Step 1 安裝RPC相關程序
執行命令:yum install inetd,這一步是為了安裝rstatd的守護進程
執行命令:yum install rusers-server
Step 2 啟動服務
service rpcbind start
service xinetd start
service rstatd start
3、構造測試用例數據
?
?
測試過程中,比較麻煩是進行大量交易hash值的構造,該值本來應該是在客戶端每次調用服務時產生,而現在是需要在進行執行壓力測試之前產生。通過post調用,在內存數據庫中產生需要的hash值,只要服務器不重啟,該值一直存在。在下面的post提交的前3個值確定構造3種交易hash的值的數量。
4、2000個并發時,Controller出現下面錯誤信息。
Action.c(35): Error -27796: Failed to connect to server "172.17.0.10:38000": [10048] Address already in use.TrychangiACAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters\TcpTimedWaitDelay to 30 and HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters\MaxUserPort to 65534 and rebooting the machine See the readme.doc file for more information
按照提示信息,判斷可能是壓測目標是一個簡單方法調用,服務器端口數不夠造成的。根據上面提示在注冊表中已將壓力機注冊表中的TcpTimedWaitDelay? 改為 1;MaxUserPort 改為 65534;并且重啟電腦,運行壓力仍出現上面的錯誤。之后在 run-time setting/browser emulation中將simulate a new user on each iteration? 選項去掉,重新運行一切正常,不再有錯誤出現。每次迭代不再模擬一個新的虛擬用戶,這樣相當于保持客戶機和服務器連接,也不用每次迭代下載數據。具體的原因需要更深入研究Loadrunner本身的機制。
5、在3臺壓力機時,壓力機本身的CPU、內存等資源充足,但是模擬的用戶數量卻上不去?
我們的壓力機安裝的windows sever 2008。在Windows計算機的標準設置下,操作系統已經默認限制只能使用最大線程數所導致。修改注冊表可以打開該限制。
(1)HKEY_LOCAL_MACHINE找到:System\CurrentControlSet\Control\Session Manager\SubSystems。
(2)找到下面字段:
%SystemRoot%\system32\csrss.exe bjectDirectory=\Windows
SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1
ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2
ProfileControl=Off MaxRequestThreads=16
其中SharedSection=1024,3072,512格式為xxxx,yyyy,zzz,其中,xxxx定義了系統范圍堆的最大值(以KB為單位),yyyy定義每個桌面堆的大小。
(3)將yyyy的設置從3072更改為8192(即8MB),增加SharedSection參數值。
通過對注冊表的更改,系統將允許運行更多的線程,產生更多的Vuser。另外,也需要調整Loadrunner本身對壓力機的控制。在loadrunner中,默認的是每50個vuser會使用一個mdrv.exe進程,可以啟動多個mdrv.exe的進程,每個進程中的vuser數量少一點,具體的辦法如下:安裝目錄下"dat"protocols"CsNet.lrp文件中,在[Vugen]下面新加一條MaxThreadPerProcess=要設置的vuser數量。這樣每個mdrv.exe進程中的vuser數量就是設置的數量。
6、Docker中JVM監控問題。
JVM監控可以使用JDK自帶的jvisualvm應用監控,通過圖形判斷比使用jstat等命令監控更方便一些。但是Docker中的JVM外部是訪問不了,所以,我們使用了jvisualvm監控了服務器的JVM。Docker內部的JVM只能通過命令行,進行監控。
7、Loadrunner在大量并發寫文件問題分析。
在大量并發用戶執行過程中,發現了Loadrunner寫文件上的問題。在兩個事務中,要把產生的hash值寫入文件中,目的是為了檢查返回的hash值是否正確。發現在記錄的文件中,大約1%左右的hash值記錄的長度超長或縮短了,Loadrunner在大量的并發用戶在同時寫一個文件時,是否會出現,一個線程時間片寫不完,下個時間片再寫導致出錯呢?或者是系統在返回hash只上面就有問題。解決方法是在寫文件時,首先對根據左右邊界找到的hash值進行長度判斷,如果長度等于要求的長度64,則寫入,否則不寫文件。這樣再次執行寫入文件時,發現還是會出現超過64個字符長度或縮短的問題,是否是loadrunner本身的問題,需要后續研究。在后面的調用查驗事務時,直接通過關聯把hash值插入,也不會出現hash值不正確問題。
8、在對運用區塊鏈技術的系統性能測試中,出現了很多問題,有些沒有在上面列出,例如,京東云的不穩定,騰訊云的不穩定,最后換成阿里云,應用服務器和壓力機才比較穩定下來。剛開始時壓力機安裝的Windows sever 2012,作為壓力機限制較多,后面換成阿里云后,全部換成Windows server 2008,遠程桌面連接和rps服務使用起來方便很多。用服務器版本作為壓力機應該不是最佳選擇,但是由于租用的服務器上無Win 7等,所以只能這樣選擇。在測試過程中,開發人員遇到系統上的問題,也會升級解決,沒有把問題全部匯總出來。
測試中的不足,由于沒有參與進行功能測試,只是根據性能指標要求進行壓力負載測試,所以對于驗證數據的返回,但是沒有驗證返回數據的正確性。由于對于云服務器的使用,包括應用服務器和壓力機,都是第一次使用,對于系統支持并發用戶的數量提前沒有估計,所以對于為達到TPS和并發用戶數,有一個試探性的過程,消耗了時間。感覺基于云的服務與物理的服務器在性能上還是會存在較大差距。
下面貼幾張監控得到的圖,以供了解。
2000并發時,TPS圖,截取持續壓力期間的圖形
2000用戶并發時,各應用服務器上的資源監控
1600和2000個并發用戶時,出現的并發超時日志截圖:
?
?
(完)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。