2019.8.10
loadrunner随机数方法汇总
1、loadrunner11中脚本中,未进行参数化策略部分的代码,如果运行场景里设置了同步初始化,那么这部分代码所有用户会公用。例如:以下是一段随机code生成的脚本,目的是为了让不同用户并发时自动使用随机实时生成的code。但是如果在场景中,
,选择了同步的初始化,那么所有用户都会使用相同的脚本,也就是会产生相同的code码。因此可以采用第二个,每个1秒初始化一个脚本来实现。
char* randstring(int slen)
{
int i, randid;
char temp[100] = "";
char character_set[52] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for(i =1; i<=slen; i++)
{
randid = rand() % 52;
sprintf(temp,"%s%c",temp,character_set[randid]);
}
return (temp);
}
Action()
{
char* code = randstring(52);
lr_save_string(lr_eval_string(code), "CODE");
lr_output_message("生成的code1为:%s", lr_eval_string("{CODE}"));
lr_save_string(lr_eval_string(randstring(52)), "CODE");
lr_output_message("生成的code2为:%s:", lr_eval_string("{CODE}"));
return 0;
}
所以,这个跟本身代码的写法没有关系。因此如果要实现随机字符:
1、不采用同步初始化。
2、使用系统自带的参数化类型:,并采用多个数字串拼接。
lr_output_message("生成的num为:%s", lr_eval_string("{str1}{str2}{str3}")); //用多个str字符串拼接,但最好其中某个str设置为时间戳,这样前后不同时间生成的随机数绝对不会重复。
3、如果还想使用自己定义的函数去生成,那么该函数编译到dll文件中,使用动态链接库。参数化类型选。
具体dll使用方法,可见这篇文章。https://blog.csdn.net/jiang1986829/article/details/48467269。这篇文章是在VS2005中编写DLL文件的,我尝试过使用C语言去编写DLL文件,但是对于C语言的语法实在不太熟悉了,因此想采用强大的PYTHON去编写。这篇文章可以考虑一下:https://www.cnblogs.com/xueliangliu/p/9375664.html。
(1)用C语言写的一个随机数生成函数:
先参考C语言从函数返回数组一文。https://www.runoob.com/cprogramming/c-return-arrays-from-function.html
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <time.h>
char* randstring(int slen) //C 语言不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。
{
int i, randid;
static char temp[100] = ""; //C 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。
char character_set[62] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
srand( (unsigned)time( NULL ) );//随机种子
for(i =1; i<=slen; i++)
{
randid = rand() % slen;
sprintf_s(temp,"%s%c",temp,character_set[randid]);
}
return (temp);
}
void main()
{
char* code = randstring(62);
printf("生成:%s", code);
}
(2)编写DLL文件,在VS2005中创建DLL项目
random_code.cpp
//注意此处的宏定义需要写在#include "TestDLL.h"之前
//以完成在dll项目内部使用__declspec(dllexport)导出
//在dll项目外部使用时,用__declspec(dllimport)导入
#define DLL_IMPLEMENT
#include "random_code.h"
#include <Windows.h>
#include <intrin.h>
#include <stdlib.h>
#include <string.h>
#include<stdio.h>
#include<string.h>
#include <time.h>
char DLL_API *randstring(int slen)
{
int i, randid;
static char temp[100] = "";
char character_set[62] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
srand( (unsigned)time( NULL ) );//随机种子
for(i =0; i<slen; i++)
{
randid = rand() % slen;
temp[i] = character_set[randid]; //C语言字符串拼接单个字符比较麻烦,只能使用赋值操作
}
return (temp);
}
头文件:random_code.h
#pragma once;
//该宏完成在dll项目内部使用__declspec(dllexport)导出
//在dll项目外部使用时,用__declspec(dllimport)导入
//宏DLL_IMPLEMENT在TestDLL.cpp中定义
#ifdef DLL_IMPLEMENT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
extern "C" DLL_API char *randstring(int slen); //简单方法
按F7编译,生成random_code.dll,放置到loadrunner工作目录下。
loadrunner脚本:
vuser_init()
{
int result;
result = lr_load_dll("random_code.dll");
if(result!=0){
return -1;
}
return 0;
}
Action()
{
lr_output_message("生成:%s", randstring(62));
return 0;
}
即可生成62位随机数。
2019.8.12
Action.c(4): Error -27796: Failed to connect to server "stadig.ifeng.com:80": [10048] Address already in use
Try changing the registry value
HKEY_LOCAL_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
压测目标是一个简单的js,服务器处理很快。LR压力测试遇到如上错误,跟据提示在注册表中已将TcpTimedWaitDelay 改为 1;MaxUserPort 改为 65534;并且重启电脑。运行后仍出现上面的错误。后来在 run-time setting/browser emulation中
将simulate a new user on each iteration 选项去掉(默认是选中的)。重新运行一切正常,没有错误出现。
猜测原因,客户端性能比较好,发出压力太快,所以把tcp/ip的连接或端口占满。在网上查了一下,xp好像默认开启15个tcp/ip
去掉这个选项的意思是,始终使用一个tcp/ip链接,不断开,也就是开发人员所说的长链接或持久连接。
短连接:建立连接-----发送和接收报文1-------关闭连接
长连接:建立连接-----发送和接收报文1.。。。2.。。。3-----关闭连接
2019.8.27
内存溢出:(out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。
内存泄漏:(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果
什么是前置:
政务系统与外网是物理隔离的,因此其间就需要一个信息交换系统,这个就是前置机。前置机一般来说是一个物理系统,它主要起到一个网关的作用,以实现内外网的信息交换。
前置机是实现银行传统业务向外拓展普遍采用的一种中间设备。它实现的主要功能有网络通信、报文认证、交易数据格式转换、个人密码PIN变换、交易流水记录、交易预处理、交易监控和交易数据统计等。目前在银行普遍采用前置机的有ATM、POS、IC卡、银联金卡、电话银行、券银通、银税通、即缴费、电子汇兑和同城清算等系统。这些前置机都具有前面所述的一种到多种功能。
2019.12.12
线程数:在性能测试优化的时候经常会涉及更改线程数。具体是什么意思呢?拿tomcat举例子:
对web应用开发者来说,我们很关心应用可同时处理的请求数,以及响应时间。应用本身和它运行在其中的web容器是两个很重要的影响因素。
对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束。如果同时进来的请求多于当前可用的请求处理线程数,额外的线程就会被创建,直到到达配置的最大线程数(maxThreads属性值)。如果仍就同时接收到更多请求,这些来不及处理的请求就会在Connector创建的Server Socket中堆积起来,直到到达最大的配置值(acceptCount属性值)。至此,任何再来的请求将会收到connection refused错误,直到有可用的资源来处理它们。
7.23
1、连接池概念
连接池其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问之后,会将连接对象归还给容器
2、连接池好处
① 节约资源(不必没连接一次数据都去创建一个 Connection 对象)
② 用户访问高效(每次连接只需要从数据库连接池中获取连接即可,不用等待连接数据库的漫长过程
3、实现
(1)标准接口:DataSource 在 javax.sql 包下
常用方法:
1 2 |
|
Connection 是从连接池中获取的,那么调用 Connection.close() 方法,则不会再关闭连接了,而是归还连接。
(2)接口的实现,一般不需要我们去实现,有数据库厂商来实现
① C3P0:数据库连接池技术
② Druid:数据库连接池技术,由阿里巴巴提供