背景

  最近项目要做性能测试,要出要一份性能报告,让我出一个有关Tcp和Udp的功能模块的测试,流程大概是这样,先走TCP协议协商一下会话,协商成功后走Udp收发数据。

  

  有点简单啊,自己写个功能模块测一下,然后把结果展示出来就ok了。

  然而想法很美好,现实有点残酷。idea瞬间被pass掉,理由就是自己写的测试模块木有说服力。

  

  要用专业的测试工具来搞,才有说服力。作为一名开发,用测试工具是不可能的,就算饿死也不会用!!!

   

  最后还是学了一下LoadRunner,在历经一番坎坷摸索之后,出了个测试脚本。不得不说,LR真的挺好用的。(PS:真香现场)

不说废话了,在网上找了一下使用LR测试TCP和UDP的脚本,资料有点难找,大多都是简单概况一下。(让我一个LR初手,搞不定啊),最后在自己一番摸索之下,把过程整理一下,要有啥不好的地方,还请多指教一下。

准备工作

  • LoadRunner 环境,这个大家自行百度,教程太多我就不详说了
  • 数据包,客户端进行TCP协商的数据包,使用udp发送的数据包(用wireshark抓取)
  • LR的测试脚本

编写测试脚本

  使用LR测试TCP和UDP要使用LR中Windows sockets协议,它可以模拟tcp/ip协议和服务器进行数据交互,这样便可以模拟终端来进行性能测试了。首先打开LR Virtual User Generator选择创建脚本。

                          图:创建脚本

  选择创建windows sockets协议的脚本。

                图:选择socket协议

接着会出来一个录制选项框,在应用类型里有两种选择,一种是win32的应用,一种是浏网络应用,选择后可以开始录制脚本,会启用对应的应用,根据操作录制脚本。

图:初始化参数

我这边使用网络应用,输入要测试服务的URL,选择对应的action,然后点击ok就可以开始录制。

这里可以选择的活动对应有三种

  • vuser_init:创建虚拟用户初始化时做的事情, 比如要测试业务某个具体业务操作环节时,可以先把系统用户登录的写在init中。
  • action:       用户操作的事件,即需要测试业务操作点。
  • vuser_end:虚拟用户退出的时候做到操作,如关闭socket等。

不过录制脚本这个功能生成的测试脚本有的时候不符合我们的预期,还是要自己修改,所以我这里随便录制了一下,然后重写脚本。

图:结束录制

点击结束录制,会生成脚本,如下图,然后我们就可以自己修改脚本了。

最后就是最关键的地方了,根据具体业务流程来编写测试脚本,我这里总体业务流程大致如下

编写vuser_init

我这里由于要协商会话,所以在初始化时需要发送两次请求和接受两次请求,脚本如下

vuser_init()
{
char*recvbuf;
int recvlen=;
int rc=; lrs_startup();
//设定开始事务
lr_start_transaction("Trans_Session");
lr_start_transaction("Conn_TCP");
//创建socket
rc=lrs_create_socket("socket0","TCP","LocalHost=0","RemoteHost=127.0.0.1:8888",LrsLastArg);
//判断套接字创建是否成功
if(rc!=){
lr_end_transaction("Conn_TCP",LR_FAIL);
lr_end_transaction("Trans_Session",LR_FAIL);
return ;
}
lr_end_transaction("Conn_TCP",LR_PASS); //判断socket是否链接成功的事务,0表示创建成功 lrs_send("socket0","senCreateReqBuf",LrsLastArg); //发送安全会话建立请求,senCreateReq为在data.ws中定义的发送变量
lrs_receive("socket0","senCreateRspBuf",LrsLastArg); //接收消息,存放在senCreateReq中,senCreateReq是在data.ws中定义的接收数组,注意数组长度一定要大于等于实际接收长度 lrs_get_last_received_buffer("socket0",&recvbuf,&recvlen);//把Socket最后接收的字节数组,长度放在recvlen中,内容放在recvbuf中 if(recvlen<) {
lr_end_transaction("Trans_Session",LR_FAIL);
} lrs_send("socket0","authReqBuf",LrsLastArg); //发送authRsp,authRsp为在data.ws中定义的发送变量
lrs_receive("socket0","authRspBuf",LrsLastArg); //接收消息,存放在authRep中,authRep是在data.ws中定义的接收数组,注意数组长度一定要大于等于实际接收长度 lrs_get_last_received_buffer("socket0",&recvbuf,&recvlen);//把Socket最后接收的字节数组,长度放在recvlen中,内容放在recvbuf中 if(recvlen>)
lr_end_transaction("Trans_Session",LR_PASS);
else
lr_end_transaction("Trans_Session",LR_FAIL);
return ; }
   1. 首选创建相关测试的事务,在性能测试中这个可以作为测试用例通过的依据lr_start_transaction与lr_end_transaction 为使用最多的事物创造组合函数,lr_start_transaction为事物开始函数,lr_end_transaction为事物结束函数,并负责记录事物的运行时间. 
语法格式如下:
  • int lr_start_transaction (const char * transaction_name);
  • int lr_end_transaction (const char * transaction_name,int status);
 其中transacton为事物名称,status为事物的结束状态,共有LR_PASS(通过)、LR_FAIL(失败)、LR_AUTO(自动)、 LR_STOP(暂停),其中LR_PASS默认的是LR_PASS,可以在事物结束前通过lr_set_transaction_status进行修改。如果在lr_end_transaction中没有指定结束事物状态是LR_AUTO,而是明确制定为LR_PASS、LR_FAIL、 LR_STOP其中的其中,则事物将以最后制定状态来结束。需要注意,事物开始没有lr_end_transaction没有结束的时候,不能用相同的事 物名称,除非这个事物已经通过lr_end_transaction结束。
2. 接着创建socket,初始化套接字,使用的函数如下
  • int lrs_create_socket("socket0","TCP","LocalHost=0","RemoteHost=127.0.0.1:8888",LrsLastArg);

参数分别是:socket名称、协议类型(TCP或UDP)、链接类型(远程链接:RemoteHost、本地:LocalHost、或者本地监听)、LrsLastArg 参数结束标记,创建成功返回0。

3. 创建完套接字后,判断时候成功,若是失败将对应的事务状态修改为LR_FAIL。

4.通过socket发送数据,lrs_send("socket0","senCreateReqBuf",LrsLastArg); 这里senCreateReqBuf为待发送的数据,数据存在data.ws文件中。


        send 后面填的是待发送数据buf的名称,接着再跟上待发送数据的长度 ,待发送buf在LR中我这边是以16进制发送,按照LR的规则需要在16进制值前中加上\x,很明显构造这个数据还是麻烦的很。所以这里提供一个比较方便的方式。

  

我们可以从wireshark中直接抓取对应格式的数据,选择需要的数据,右键复制,选择转义字符串,就可以了,最后将复制的数据放在data.ws中就可以了。

5.接收响应数据,判断响应数据是否正确,我这里根据长度来判断。

编写Action

在Action文件中编写需要测试的操作步骤,我这里就是发送udp请求,接受响应,判断响应是否正确,代码如下

Action()
{
char*recvbuf;
int recvlen=;
int rc=; lr_start_transaction("Trans_UDP");
lr_start_transaction("Conn_UDP"); rc=lrs_create_socket("socket1","UDP","RemoteHost=127.0.0.1:8887",LrsLastArg);
if (rc != ) {
lr_end_transaction("Conn_UDP",LR_FAIL);
lr_end_transaction("Trans_UDP",LR_FAIL);
return ;
} lr_output_message("Received:%d",rc);
lr_end_transaction("Conn_UDP",LR_PASS); lrs_send("socket1","ReqBuf",LrsLastArg); //发送ReqBuf,ReqBuf为在data.ws中定义的发送变量
lrs_receive("socket1","RspBuf",LrsLastArg); //接收消息,存放在RspBuf中,RspBuf是在data.ws中定义的接收数组,注意数组长度一定要大于等于实际接收长度 lrs_get_last_received_buffer("socket1",&recvbuf,&recvlen);//把Socket最后接收的字节数组,长度放在recvlen中,内容放在recvbuf中 if(recvlen>=) {
lr_end_transaction("Trans_UDP",LR_PASS);
} else {
lr_log_message("Error UDP Received length:%d",recvlen);
lr_end_transaction("Trans_UDP",LR_FAIL);
}

//--------------断开socket--------------
lrs_disable_socket("socket1",DISABLE_SEND_RECV); //--------------关闭socket--------------
lrs_close_socket("socket1"); return ; }

原理和上文提的基本一致,这里就不再多说了

编写vuser_end

编写结束时的操作,这里就是关闭init中的socket
vuser_end()
{
//--------------断开socket--------------
lrs_disable_socket("socket0", DISABLE_SEND_RECV); //--------------关闭socket--------------
lrs_close_socket("socket0");
return ;
}

运行测试脚本

点击start,执行脚本,运行无误,说明脚本正确

至此测试脚本编写完毕,可以正式开始性能测试了

性能测试

  • 始运行LR执行性能测试

  • 这里我们将刚刚编写好的的测试脚本添加进去

  • 然后配置相关的测试参数,如并发数,测试时间等,开始测试

  • 观察测试结果

最后在运行结束后,我们可以根据分析报告诊断性能测试结果,还可以配合jvisualvm工具诊断热点方法,提升程序性能

总结

我们可以LR可以配合jvisualvm工具诊断热点方法,提升程序性能。如果有大神看出什么端倪的话,欢迎批评斧正,个人感觉还有提升空间

记一次使用LR测试UDP和TCP的过程的更多相关文章

  1. 记2018/5/5 qbxt 测试

    记2018/5/5 qbxt 测试 竞赛时间: 2018 年 5 月 5 日 13:30-17:00 T1 一.maze(1s,512MB): 简单的迷宫问题:给定一个n*m的迷宫,.表示可以通过,# ...

  2. 初识-----基于Socket的UDP和TCP编程及测试代码

    一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...

  3. LR 测试http协议xml格式数据接口

    Action() { lr_start_transaction("T1"); web_custom_request("xxxxHTTPRequest", &qu ...

  4. 记2018/4/29 qbxt 测试

    记 2018/4/29  qbxt 测试(提高基础班) 简单的 NOIP 模拟赛 竞赛时间: 2018 年 4 月 29 日 13:30-17:00 题目名称 乘法 求和 计数 输入文件名 mul.i ...

  5. DNS分别在什么情况下使用UDP和TCP

    DNS同时占用UDP和TCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP栈也算是个另类.但很少有人知道DNS分别在什么情况下使用这两种协议.     如果用wiresha ...

  6. Http UDP还是TCP

    http://1024monkeys.wordpress.com/2014/04/01/game-servers-udp-vs-tcp/ 在编写网络游戏的时候,到底使用UDP还是TCP的问题迟早都要面 ...

  7. 游戏服务器:到底使用UDP还是TCP

    http://blog.jobbole.com/64638/ 在编写网络游戏的时候,到底使用UDP还是TCP的问题迟早都要面对. 一般来说你会听到人们这样说:“除非你正在写一个动作类游戏,否则你就用T ...

  8. 【转帖】计算机网络协议(三)——UDP、TCP、Socket

    计算机网络协议(三)——UDP.TCP.Socket 2019年09月04日 11:09:41 to_be_better_one 阅读数 28794 文章标签: 计算机网络UDPTCPSocket 更 ...

  9. 传输层-Transport Layer(下):UDP与TCP报头解析、TCP滑动窗口、TCP拥塞控制详解

    第六章 传输层-Transport Layer(下) 上一篇文章对传输层的寻址方式.功能.以及流量控制方法做了简短的介绍,这一部分将介绍传输层最重要的两个实例:TCP协议和UDP协议,看一看之前描述的 ...

随机推荐

  1. 自己实现AOP,AOP实现的步骤分解

    自己实现简易的AOP 一.需求:自己实现AOP:1.0版本:在某个方法上加"@InOutLog"注解,那么执行到该方法时,方法的前面.后面会输出日志信息. [自己实现AOP 2.0 ...

  2. K8s集群部署(三)------ Node节点部署

    之前的docker和etcd已经部署好了,现在node节点要部署二个服务:kubelet.kube-proxy. 部署kubelet(Master 节点操作) 1.二进制包准备 [root@k8s-m ...

  3. 用.NET Core实现一个类似于饿了吗的简易拆红包功能

      需求说明 以前很讨厌点外卖的我,最近中午经常点外卖,因为确实很方便,提前点好餐,算准时间,就可以在下班的时候吃上饭,然后省下的那些时间就可以在中午的时候多休息一下了. 点餐结束后,会有一个好友分享 ...

  4. C++ 洛谷 2014 选课 from_树形DP

    洛谷 2014 选课 没学树形DP的,看一下. 首先要学会多叉树转二叉树. 树有很多种,二叉树是一种人人喜欢的数据结构,简单而且规则.但一般来说,树形动规的题目很少出现二叉树,因此将多叉树转成二叉树就 ...

  5. SpringBoot使用Docker快速部署项目

    1.简介 建议阅读本文最好对Dokcer有一些了解 首先我们先了解一下Docker是什么 Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口.它是目前最流行的 Linux 容器 ...

  6. c# 图文添加文字斜水印

    项目中有个添加水印的需求,需要给图片铺满斜水印. 网上搜了半天全是添加在图片上.下.左.右的案例. 于是按照网上的某一段案例自己修改了一些代码. Bitmap bitmap = new Bitmap( ...

  7. 基数排序的可复用实现(C++11/14/17/20)

    基数排序,是对整数类型的一种排序方法,有MSD (most significant digit)和LSD (least significant digit)两种.MSD将每个数按照高位分为若干个桶(按 ...

  8. 不要再问我Java程序是怎么执行的了!

    什么是Java虚拟机? 要弄明白Java程序的执行过程首先要了解一下Java虚拟机 虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机有自己完善的硬体架构, ...

  9. 【Spring容器】项目启动后初始化数据的两种实践方案

    早期业务紧急,没有过多的在意项目的运行效率,现在回过头看走查代码,发现后端项目(Spring MVC+MyBatis)在启动过程中多次解析mybatis的xml配置文件及初始化数据,对开发阶段开发人员 ...

  10. CI工具Jenkins的安装配置【linux】——jenkins集成sonarqube-异常解决

    Setup 官网https://jenkins.io/ 下载war包,扔到tomcat下启动即可. 如果有port限制,在iptables中打开商品限制. 访问http://ip:port/jenki ...