qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          性能測試分享—LoadRunner篇

           之前寫了一篇JMeter的性能測試工具的使用,但是LoadRunner才算是真正重量級的性能測試工具,下面詳細介紹一下java vuser協議的使用和環境參數調試。
            LoadRunner性能測試工具使用:
            1、新建腳本,選擇java vuser協議。初步結構是
          import lrapi.lr;
          public class Actions
          {
          //在init方法里面編寫一個虛擬用戶循環只執行一次的方法,如可以把協商寫在里面,就可以達到每個用戶協商一次之后,就不再協商的效果
          public int init() throws Throwable {
          return 0;
          }//end of init
          //在aciton方法里面編寫需要循環并發的業務方法,如交易的方法,在run_time settings中設置循環的次數。
          public int action() throws Throwable {
          return 0;
          }//end of action
          //在end方法里面編寫最后要執行的方法,如釋放資源,沒有可以不寫。
          public int end() throws Throwable {
          return 0;
          }//end of end
          }
            2、在初始代碼的基礎上繼續編寫業務方法。需要注意的是:
            1)把只需要創建一次對象的語句如:Random rd = new Random();放在init,aciton,end方法之外,可以避免在循環中創建很多的對象。但是需要注意的是如果是創建HTTP請求的對象是需要反復創建的,不能單提出來,否則執行一次之后,該連接被釋放了,而沒有創建新的連接,第二次就執行不下去了。
            2)腳本編寫完之后,將該腳本所有import的類的jar包放在一個文件夾下,點擊Run Time Settings的classpath,把所有jar包都添加進去。
            3)運行腳本,看看能不能成功執行,按照錯誤提示調試腳本。
            4)接下來,可以把需要變化的值進行參數化。如商戶名和AESKEY。選中值,右鍵選擇replace with a parameter,在parameter list功能里添加需要用到的商戶和AESKEY的值,將商戶參數的循環方式select next row選擇unqie,update value on選擇once,表示為個商戶只取唯一的值。aeskey的select next row選擇same line as merchant。
            5)接下來插入事物,把需要計算業務時間的代碼前后都插入事物函數,如lr.start_transaction("pay");lr.end_transaction("pay", lr.AUTO);如果想更加詳細的知道每一步操作的時間,可以多插入一些事物,如加密,解密,獲取返回值等步驟均插入事物函數。
            6)如果需要并發執行,還需要插入集合點函數lr.rendezvous("pay");這樣在場景里并發執行的時候,所有的虛擬用戶會等到都準備好之后在一個時間點執行。

            7)接下來就是在場景里執行了。點擊tools---create controller scenario。進入場景。并發10個用戶執行5分鐘。同時監控tomcat的日志。
            在并發的情況下,出現了一些問題,下面針對這些問題給出解決方案。
            遇到的問題1、在并發執行1分鐘后,開始有報錯,主要的報錯是解密失敗,同時tomcat掛了,不能在接受新的請求。
            找到問題根源:通過監控tomcat日志,發現后期有很多的報錯日志是文件打開過多。
            嚴重: Socket accept failed java.net.SocketException: 打開的文件過多 at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408) at java.net.ServerSocket.implAccept(ServerSocket.java:462) at java.net.ServerSocket.accept(ServerSocket.java:430) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:352) at java.lang.Thread.run(Thread.java:662) 2013-5-16 11:38:46 org.apache.tomcat.util.net.JIoEndpoint$Acceptor run 2013-05-16 11:38:44,974 INFO [DefaultRequestDirector.java:586] - I/O exception (java.net.SocketException) caught when connecting to the target host: 打開的文件過多 2013-05-16 11:38:44,974 ERROR [CreditPay.java:167] - 信用卡支付失敗 com.yibao.payapi.client.RequestApiException: 請求服務未正常返回[statuscode:404, text:<html><head><title>Apache Tomcat/6.0.29 -
            解決方案:由于建立SOCKET會占用一個系統句柄,效果類似于打開了一個文件。LINUX默認的最大文件打開個數是1024(可能不同內核版本不一樣),所以如果并發太多連接時就會報錯。需要修改文件打開數設置。
            當前設置最大打開文件數可以通過如下命令查看。    ulimit -n
            這個數字說明了一個普通用戶能夠在一個單獨會話中所能打開最大的文件數目。注意。如果是root,以下操作不能使ulimit -n的輸出增加。因為用戶root用戶不受這個ulimit限制。只有普通用戶才會受這個限制。
            為了提高最大打開文件數到默認值1024以上, 需要在系統上修改2個地方。 在這個案例中, 我們將最大打開文件數增加到為65535(系統部給出的建議)。 所有的步驟需要root用戶操作。
            1、/etc/pam.d/login 添加 session required     /lib/security/pam_limits.so
            2. 按照最大打開文件數量的需求設置系統, 并且通過檢查/proc/sys/fs/file-max文件來確認最大打開文件數已經被正確設置。 echo 65535 > /proc/sys/fs/file-max
            3、在/etc/security/limits.conf文件中設置最大打開文件數,添加2行內容:
            * soft nofile 4096 * hard nofile 4096
            解釋:下面是一行提示
            #<domain>      <type>  <item>         <value>添加如下這行。 * - nofile 2048 這行設置了每個用戶的默認打開文件數為2048。 注意"nofile"項有兩個可能的限制措施。 就是<type>項下的hard和soft。 要使修改過得最大打開文件數生效,必須對這兩種限制進行設定。 如果使用"-"字符設定<type>, 則hard和soft設定會同時被設定。
            硬限制表明soft限制中所能設定的最大值。 soft限制指的是當前系統生效的設置值。 hard限制值可以被普通用戶降低。但是不能增加。 soft限制不能設置的比hard限制更高。 只有root用戶才能夠增加hard限制值。
            遇到的問題2:在虛擬用戶少的時候并發沒有再出現文件打開過多的錯誤,在并發量達到30,運行時間達到3分鐘的時候,有報錯:HTTP-500
            找到問題根源:通過查看tomcat和程序的日志,看到有大量的http-500的錯誤,是nginx已經拒絕了請求。
            解決方案:修改nginx配置文件
            vi /etc/nginx/nginx.conf
            events {
            worker_connections 1024;
            }
            調整為
            events {
            worker_connections 65535;
            }

           最后附上我寫的信用卡支付的腳本:
          /*
          * LoadRunner Java script. (Build: _build_number_)
          *
          * Script Description:
          *
          */
          import lrapi.lr;
          import http.HttpClient4;
          import http.HttpParameter;
          import http.HttpResp;
          import http.JsonUtil;
          import http.Testcredit;
          import org.apache.commons.httpclient.HttpClient;
          import org.apache.commons.httpclient.HttpException;
          import org.apache.commons.httpclient.methods.PostMethod;
          import java.util.Random;
          import java.util.Date;
          import java.text.SimpleDateFormat;
          import java.util.Calendar;
          import com.yeepay.g3.utils.common.encrypt.AES;
          import com.yibao.utils.des3.RSA_Encrypt;
          public class Actions
          {
          public  String aes;
          Date d = new Date();
          Testcredit tc = new Testcredit();
          SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
          HttpParameter parameter = new HttpParameter();
          public int init() throws Throwable {
          String url = "http://xxxxx/xxxxx/consult";
          HttpClient4 client =HttpClient4.createDefault();
          String data = "";
          Calendar now = Calendar.getInstance();
          now.setTime(d);
          String dateline=format.format(now.getTime());
          System.out.println(dateline);
          Date date = format.parse(dateline);
          String dates=date.getTime()/1000+"";
          System.out.println(dates);
          try {
          data = AES.encryptToBase64(dates, "<aes>");
          } catch (Exception e) {
          e.printStackTrace();
          }
          parameter.add("data", data);
          parameter.add("merchantaccount", "<merchant>");
          HttpResp resp = new HttpResp();
          try{
          resp=client.doPost(url, parameter, "utf-8");
          String respStr= resp.getText("utf-8");
          System.out.println(respStr);
          aes=AES.decryptFromBase64(respStr, "<aes>");
          System.out.println("aes="+aes);
          } catch (Exception e) {
          e.printStackTrace();
          }
          client.shutdown();
          return 0;
          }//end of init
          public int action() throws Throwable {
          StringBuilder sb = new StringBuilder("");
          Random rd = new Random();
          for(int i=1;i<=6;i++){
          int sr=rd.nextInt(9);
          sb.append(String.valueOf(sr));
          }
          String key=sb.toString();
          int rds=rd.nextInt(999999);
          lr.start_transaction("pay");
          lr.rendezvous("pay");
          HttpClient client = new HttpClient();
          PostMethod method = new PostMethod("http://xxxxxxxx/xxxxxxx/api/bankcard/credit/pay");
          System.out.println(aes);
          String PUBLIC_KEY=aes;
          System.out.println("PUBLIC_KEY"+PUBLIC_KEY);
          String encryptkey = "0123456789"+key;
          String merchantAccount = "<merchant>";
          //民生
          String cardNo = "6XXXXXXXXXXXXXX";
          String validthru = "XXXX";
          String cvv2 = "XXX";
          String phone = "13466745431";
          String orderId = rds+"334234223"+key;
          System.out.println(orderId);
          Integer transtime = (int)(System.currentTimeMillis()/1000);
          Integer currency = 156;
          String  amount = "50";
          String productcatalog = "1";
          String productName = "123";
          String productDesc = "小丸子";
          String userIp = "123.45.45.45";
          String identityId = "a";
          Integer identityType = 6;
          String other = "eeee";
          String data = "{\"merchantaccount\":\"" + merchantAccount
          +"\",\"cardno\":\"" + cardNo
          + "\",\"validthru\":\"" + validthru
          + "\",\"cvv2\":\"" + cvv2
          + "\",\"phone\":\"" + phone
          + "\",\"orderid\":\"" + orderId
          + "\",\"transtime\":" + transtime
          + ",\"currency\":" + currency
          + ",\"amount\":" + amount
          + ",\"productcatalog\":\"" + productcatalog
          + "\",\"productname\":\"" + productName
          + "\",\"productdesc\":\"" + productDesc
          + "\",\"userip\":\"" + userIp
          + "\",\"identityid\":\"" + identityId
          + "\",\"identitytype\":" + identityType
          + ",\"other\":\"" + other + "\"}";
          data = AES.encryptToBase64(data, encryptkey);
          try {
          method.setParameter("merchantaccount", merchantAccount);
          method.setParameter("data", data);
          method.setParameter("encryptkey", RSA_Encrypt.encrypt(encryptkey, PUBLIC_KEY));
          client.executeMethod(method);
          System.out.println(method.getStatusLine());
          String respStr = method.getResponseBodyAsString();
          System.out.println(respStr);
          String result = AES.decryptFromBase64(respStr, encryptkey);
          System.out.println(result);
          method.releaseConnection();
          } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();}
          lr.end_transaction("pay", lr.AUTO);
          return 0;
          }//end of action
          public int end() throws Throwable {
          return 0;
          }//end of end
          }
          相關文章:
          性能測試分享—JMeter篇

          posted on 2014-01-03 13:42 順其自然EVO 閱讀(425) 評論(1)  編輯  收藏 所屬分類: loadrunner

          評論

          # re: 性能測試分享—LoadRunner篇 2014-01-03 20:55 私人訂制

          好久不用這東西了  回復  更多評論   

          <2014年1月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 吴江市| 湖北省| 铜梁县| 新晃| 县级市| 宜章县| 韩城市| 柳河县| 高淳县| 临朐县| 闸北区| 交城县| 游戏| 井陉县| 景洪市| 广安市| 紫金县| 乌拉特后旗| 普安县| 常宁市| 邓州市| 西丰县| 镇宁| 龙川县| 精河县| 平乐县| 车致| 休宁县| 长寿区| 特克斯县| 吉隆县| 隆化县| 宁化县| 定安县| 吉木乃县| 西林县| 金川县| 道孚县| 雅江县| 潮安县| 海阳市|