基於區塊鏈技術的性能測試

 

作者:大開科技-曹向志

摘要:本次測試是受甲方公司委託,對運用區塊鏈技術的一個應用後臺系統進行負載測試,主要是評估系統在系統資源正常利用率下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

測試環境拓撲圖如下:

clip_image002

性能測試需求分析:

該系統主要對併發用戶數、響應時間、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個交易方法,只是提供測試調用接口即可。最後通過商議,開發決定採用第二種方案。這可能是開發覺得比較安全的方式。:)

clip_image003

基本賬戶轉賬的訪問代碼如下:

web_set_max_html_param_len("300000");

lr_start_transaction("基本賬戶轉賬300");

web_reg_save_param("txhash1","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("{txhash1}"))==64)

fprintf( fp1,"%s\n",lr_eval_string("{txhash1}") );

else

fprintf( fp20,"%s\n",lr_eval_string("{txhash1}") );

 

上面代碼是運用到每一個節點。代碼中主要通過註冊函數獲得訪問基本交易轉賬返回的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、構造測試用例數據

clip_image004

 

 

測試過程中,比較麻煩是進行大量交易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圖,截取持續壓力期間的圖形

clip_image006

2000用戶併發時,各應用服務器上的資源監控

clip_image008

1600和2000個併發用戶時,出現的併發超時日誌截圖:

clip_image010

 

 

(完)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章