投票接口压测

一、压测需求:

关于app的投票功能,涉及两个接口:1、首先是登录接口,登录成功提交后,会返回登录认证用的token值,token值会过期。2,然后投票接口的url中用”?”拼接token值,进行投票

针对投票只能一天10次的限制,经沟通后压测期间放开,目前可以使用同一个账号/多个账号,对一个人进行无限次投票

二、测试脚本分析:

常见的app接口的压测,关注点是服务器的处理能力时,一般选择的方式是监听抓取,可以使用电脑分享热点,手机连接热点后,设置静态ip,使用fiddler监听指定的端口,

http的请求相对简单,直接就能抓取到,但本次压测涉及到的请求为https需要安装证书配置环境且研发提供了对应的接口文档,所以可以直接使用loadrunnner构造请求。

三、相关接口:

【涉及到生产环境,故只记录传递的参数,url1表示登录的url地址,url2表示投票的url地址】

登录接口:url1

入口参数:JSON格式

{"account":"root-xj","pwd":"meta"}

返回参数:JSON格式

 {
    "result": "success",
    "msg": "操作成功",
    "token": "963e5d032e00d559c765c474a18e5bfe302e4c1e",

..... 

}

投票接口:url2?token=*****

入口参数:JSON格式

{"userorcomuuId":"18611111111","userorcom":"c1","votecategoryId":"v1"}

返回参数:JSON格式

 {"result":"success","msg":"投票成功"}

四、脚本 

此次压测使用的工具是loadrunner,脚本的思路如下:

使用loadrunner自带的web_custom_request()函数进行post请求体的构造。登录请求的返回值进行动态关联获取,参数化名为getTokenid,将该值传入到投票请求的url中,进行投票提交。

增加两个文本检查点:1)登录成功的验证 2)投票成功的验证

Action()
{
//动态关联,根据左右边界值,获取tokenid
    web_reg_save_param("getTokenid",
        "LB=\"token\":\"",
        "RB=\"",
        "NotFound=ERROR",
        LAST);
 //文本检查点,判断是否登录成功,由于回放response是乱码,因此直接使用乱码作为检查点就可以
    web_reg_find("Fail=NotFound",
        "Text=鎿嶄綔鎴愬姛",
        LAST);

//构造登录请求,名称自定义,URL为请求的接口地址,Method为请求用到的方法,body体中为请求用到的json参数,注意转移字符“\”的使用
    web_custom_request("web_custom_request",
    "URL=https://url1",
        "Method=POST",
        "TargetFrame=",
        "Resource=0",
        "EncType=application/json", //编码类型,指定请求头的content-type互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。   
        "Referer=",
        "Body={\"account\":\"root-xj\",\"pwd\":\"meta\"}",
        LAST);

    web_reg_save_param("res",
        "LB=",
        "RB=",
        LAST);

//检查点,验证是否投票成功
    web_reg_find("Fail=NotFound",
        "Text=鎶曠エ鎴愬姛",
        LAST);
 
//添加投票的事务
    lr_start_transaction("投票");

//构造投票请求的post请求体,尤其注意 EncType=application/json
    web_custom_request("vote",    
"URL=https://url2?token={getTokenid}", "Method=POST", "TargetFrame=", "Resource=0", "Referer=", "EncType=application/json", "Mode=HTML", RAW_BODY_START,
"{\"userorcomuuId\":\"18611111111\",\"userorcom\":\"c1\",\"votecategoryId\":\"v1\"}", 70, RAW_BODY_END, //"Body=\{\"userorcomuuId\":\"18611111111\",\"userorcom\":\"c1\",\"votecategoryId\":\"v1\"\}", LAST); lr_end_transaction("投票", LR_AUTO); lr_output_message(lr_eval_string("{res}")); return 0; }

 五、脚本调试遇到的问题

  • HTTPS请求报错

  报错信息:

  Action.c(15): Error-27780: [GENERAL_MSG_CAT_SSL_ERROR] connect to host "www.txbzjl.com" failed: [10054] Connection reset by peer  [MsgId: MERR-27780]

  解决办法:

  Vuser-RuntimeSetting中设置勾选“Winlnet replay instead of Sockets(windows only)”

  • HTTP Status 500

  报错信息:

       org.codehaus.jettison.json.JSONException: A JSONObject text must begin with '{' at character 0 of

  解决思路:

  1) root cause的报错信息,字面意思是:一个JSON对象必须以“{”开始,错误第0个字符。出现这个异常的原因是json串格式不正常,没有"{"开始或没有"}"结尾,

  仔细检查下json文件的格式一般就可以解决这个问题。

  2) 需要如果在发送请求不加"EncType=application/json",请求头发出去的默认enctype就是“application/x-www-form-urlencoded”, 窗体数据被编码为名称/值对。

  3) 在解析流的过程中,首先是将传递的字符串使用解析器,进行解析,然后转换格式为指定的类型:一个是JSONarray一个是jsonObject,出现这种报错的问题有可能是,

       本应当以JSONArray来处理的元素,却被当做JSONObject来对待,而字符串的形式却是[],不是以{}的形式存在,导致报错。

 六、压测中发现的问题

在并发100,加入检查点,同时投给一个人,持续压入3w投票数据后,发现手机端显示的该人的投票数与loadrunner的成功事务数/后台统计的总投票数,不一致,只有1w多票。

经过分析排查,导致这个问题的原因是,压测时多线程并发,研发在后台的投票方法中,没有加锁。但是加了锁以后,在并发使用时,会导致很大程度上的等待,又使用了java多线程处理,

这样在并发时,一是保证了响应时间,一是保证了数据的准确性。

posted @ 2017-12-07 11:42  鲸落丶  阅读(918)  评论(0编辑  收藏  举报