標籤:
發現問題的應用情境
C/S結構程式,請求響應採用非同步機制。即用戶端發送一個請求後不是一直等待這個結果,用戶端將請求存放在請求隊列並獲得一個JOBID,伺服器運行後將運行結果存放在響應隊列,用戶端定時查看響應隊列,根據JOBID定時從響應隊列中擷取結果。因此帶來的測試問題是受伺服器狀態影響,用戶端擷取結果的次數不固定。
測試指令碼樣本
lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=localhost:8080", LrsLastArg);
lrs_send("socket0", "buf56", LrsLastArg);
lrs_receive("socket0", "buf57", LrsLastArg);
GetJobID();
do{
lr_think_time(0.3);
lrs_send("socket0", "buf58", LrsLastArg);
lrs_receive("socket0", "buf59", LrsLastArg);
}while(!CheckStatus());
其中buf56、57是發送請求,buf58、59是迴圈去擷取結果並檢查返回的標誌位,若仍沒有結果返回則在一定時間後迴圈擷取結果,因此請求數不固定。
LR提示socket異常
當我用lrs_create_socket建立串連之後,當這個socket串連的請求次數達到100次後,這個串連就不可用了,必須close後再重新create。LoadRunner提示錯誤:Error : socket0 - Software caused connection abort. Error code : 10053.
問題驗證
一開始認為是LoadRunner對Socket的支援問題,因為同樣的測試方式在Rational Robot中可以通過。於是做了最簡單的一個實驗:
1、用socket方式錄製訪問某個網頁並儲存(如baidu、或tomcat的預設頁面)
2、添加迴圈方式去訪問
結果證明在socket請求次數達到100後即無法再次訪問了(少數次數可以達到一百零幾)。
指令碼如下:
#include "lrs.h"
int i;
Action()
{
lr_think_time(1);
lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=appsvr01:8080", LrsLastArg);
i=1;
do{
lrs_send("socket0", "buf0", LrsLastArg);
lrs_receive("socket0", "buf1", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
lrs_send("socket0", "buf2", LrsLastArg);
lrs_receive("socket0", "buf3", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
lrs_send("socket0", "buf4", LrsLastArg);
lrs_receive("socket0", "buf5", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
lrs_send("socket0", "buf6", LrsLastArg);
lrs_receive("socket0", "buf7", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
}while(i<200);
return 0;
}
LoadRunner VUGen日誌如下:
...
lrs_send(socket0, buf2)
Action.c(21): lrs_receive(socket0, buf3)
Action.c(22): -------------lrs request times: 98
Action.c(24): lrs_send(socket0, buf4)
Action.c(25): lrs_receive(socket0, buf5)
Action.c(26): -------------lrs request times: 99
Action.c(28): lrs_send(socket0, buf6)
Action.c(29): lrs_receive(socket0, buf7)
Action.c(29): Mismatch (expected 1249 bytes, 1268 bytes actually received)
Action.c(30): -------------lrs request times: 100
Action.c(16): lrs_send(socket0, buf0)
Action.c(17): lrs_receive(socket0, buf1)
Action.c(17): Error : socket0 - Software caused connection abort. Error code : 10053.
Abort was called from an action.
Ending Vuser...
Starting action vuser_end.
vuser_end.c(12): lrs_cleanup()
Ending action vuser_end.
新的發現
在發現以上問題後百思不得其解之後即和一些測試朋友進行討論交流,但同樣沒有什麼頭緒。在一次交流中意外發現朋友的測試指令碼中串連的是80連接埠,於是推斷他是用IIS作為測試伺服器,突然意識到這是否和應用伺服器也有關,立即採用IIS作為伺服器進行測試,居然測試通過了,並沒有出現Socket串連問題!隨後用Weblogic進行測試也同樣通過!
初步結論
由以上的各種驗證方法發現問題並非單獨由LoadRunner引起的,而是和測試的應用伺服器也有很大關係。僅當用LoadRunner測試Jboss、Tomcat伺服器時才會出現這種問題,而對IIS、Weblogic等問題並不存在。但另有一個奇怪的問題是採用Rational Robot用同樣的測試方法,所有的伺服器類型都沒有問題!
在尋找的過程中突然發現了一些關於HTTP的資訊,具體如下:
KeepAlive On
在HTTP 1.0中,一次串連只能作傳輸一次HTTP請求,而KeepAlive參數用於支援HTTP 1.1版本的一次串連、多次傳輸功能,這樣就可以在一次串連中傳遞多個HTTP請求。雖然只有較新的瀏覽器才支援這個功能,但還是開啟使用這個選項。
MaxKeepAliveRequests 100
MaxKeepAliveRequests為一次串連可以進行的HTTP請求的最大請求次數。將其值設為0將支援在一次串連內進行無限次的傳輸請求。事實上沒有客戶程式在一次串連中請求太多的頁面,通常達不到這個上限就完成串連了。
KeepAliveTimeout 15
KeepAliveTimeout測試一次串連中的多次請求傳輸之間的時間,如果伺服器 已經完成了一次請求,但一直沒有接收到客戶程式的下一次請求,在間隔超過了 這個參數設定的值之後,伺服器就中斷連線。
在對伺服器設定檔進行了MaxKeepAliveRequests參數設定後,測試指令碼請求次數順利突破了原有的極限,問題都得到瞭解決!
---------------------------------------------------------------------------------------------------------------------------------------
測試情境: tomcat 做server, 使用LR 測試上傳檔案的效能。
LoadRunner總是報錯:“Action.c(81): Error -27792: Failed to transmit data to network: [10053] Software caused connection abort”
解決方案:
(1)添加配置 maxKeepAliveRequests=”-1”
Description: The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.
(2)適當加大 connectionTimeout="60000"
Description: The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. The default value is 60000 (i.e. 60 seconds).
----------------------------------------------------------------------------------------------------------------------------------------------
在今天的測試過程中發現,socket請求串連時總是出錯,code是10053,google後把問題已經解決了。關鍵的點就在於Web伺服器(Tomcat/Jboss)的一個參數的配置. "MaxKeepAliveRequests"
MaxKeepAliveRequests為一次串連可以進行的HTTP請求的最大請求次數,其預設值為100。如果將其值設為-1便可支援在一次串連內進行無限次的傳輸請求。事實上沒有客戶程式在一次串連中請求太多的頁面,通常達不到這個上限就完成串連了。
知道了問題的原因,解決起來就好辦了。可以修改或者添加tomcat設定檔server.xml中的連接器(<Connector ... />)的配置。
<Connector port="8090" protocol="HTTP/1.1"
connectionTimeout="20000"
maxKeepAliveRequests="-1"
redirectPort="8443" />
maxKeepAliveRequests="-1"表示: 將支援在一次串連內進行無限次的傳輸請求
---------------------------------------------------------------------------------------------------------------------------------------------
問題描述:
在用winsocket協議錄製指令碼後,回放指令碼結果報(Software caused connection abort,10053 error)。
現場解決過程:
1、 經查資料,好多地方說這是由於指令碼沒有關聯的原因,於是先對指令碼進行參數化及關聯,並確保這兩項工作設定正確,然後回放指令碼,結果指令碼還報10053錯誤。
2、於是開始查HP官方資料及國外網站,結果有人說這是因為應用伺服器keppalive參數設定過小,於是開始設定這些參數,結果指令碼還報10053錯。
3、鬱悶至及,便將之先放到一邊,三天后某一天突然靈感突發有了一個思想法:目前錄製的指令碼中開啟了好多socket,那麼是不是因為開啟的多使得資料不能正確傳輸,於是立刻進行嘗試,讓指令碼運行時每時每刻只有一個socket在開啟,當這個socket運行上一會後再將其關閉新開一個新的。很類似將以下內容
{
lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=www.milivio.com.cn:80", LrsLastArg);
lrs_send("socket0", "buf0", LrsLastArg);
lrs_receive("socket0", "buf1", LrsLastArg);
lrs_create_socket("socket1", "TCP", "LocalHost=0", "RemoteHost=www.milivio.com.cn:1433", LrsLastArg);
lrs_send("socket1", "buf2", LrsLastArg);
lrs_receive("socket1", "buf3", LrsLastArg);
lrs_send("socket1", "buf4", LrsLastArg);
lrs_receive("socket1", "buf5", LrsLastArg);
}
修改為
{
lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=www.milivio.com.cn:80", LrsLastArg);
lrs_send("socket0", "buf0", LrsLastArg);
lrs_receive("socket0", "buf1", LrsLastArg);
lrs_send("socket0", "buf2", LrsLastArg);
lrs_receive("socket0", "buf3", LrsLastArg);
lrs_close_socket("socket0");
lrs_create_socket("socket1", "TCP", "LocalHost=0", "RemoteHost=www.milivio.com.cn:1433", LrsLastArg);
lrs_send("socket1", "buf4", LrsLastArg);
lrs_receive("socket1", "buf5", LrsLastArg);
}
這樣一做,大功告成!
LoadRunner Error code 10053,Software caused connection abort