发布新日志

  • 性能测试群

    2012-09-07 15:19:34

    群号:70408367
     
    非专业不开服,诚交天下英杰!
  • Abnormal termination, caused by mdrv process termination.(转)

    2012-06-13 10:30:30

    1. Load generator跑了太多用户导致CPU和内存爆满,进程无法处理请求
    2. 确认自定义的代码是否释放内存
    3. 合理调整或增加思考时间
    4. 关闭extended log
    5. 尽量避免使用Load generator本身测试机做压力测试
    6. 增加迭代次数
    7. 打开loadrunner installation\config\wlrun7.ini 调整AgentMaxThreadsPerDriver=50 为 AgentMaxThreadsPerDriver=20或 10
    8. Runtime Settings > Miscellaneous > Multithreading > RunVuser as a process
    9. LR 安装目录dat\protocols下的CsNet.lrp文件中[Vugen]下面新加一条MaxThreadPerProcess=要设置的vuser数量
  • loadrunner中MD5加密实现

    2012-06-12 10:40:41

    globals.h引入如下:
    ifndef _GLOBALS_H
    #define _GLOBALS_H

    //--------------------------------------------------------------------
    // Include Files
    #include "lrun.h"
    #include "web_api.h"
    #include "lrw_custom_body.h"

    //--------------------------------------------------------------------
    // Global Variables

    #endif // _GLOBALS_H
    #ifndef MD5_H
    #define MD5_H
    #ifdef __alpha
    typedef unsigned int uint32;
    #else
    typedef unsigned long uint32;
    #endif
    struct MD5Context {
            uint32 buf[4];
            uint32 bits[2];
            unsigned char in[64];
    };
    extern void MD5Init();
    extern void MD5Update();
    extern void MD5Final();
    extern void MD5Transform();
    typedef struct MD5Context MD5_CTX;
    #endif
    #ifdef sgi
    #define HIGHFIRST
    #endif
    #ifdef sun
    #define HIGHFIRST
    #endif
    #ifndef HIGHFIRST
    #define byteReverse(buf, len)    /* Nothing */
    #else
    void byteReverse(buf, longs)unsigned char *buf; unsigned longs;
    {
        uint32 t;
        do {
        t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |((unsigned) buf[1] << 8 | buf[0]);

        *(uint32 *) buf = t;
        buf += 4;
        } while (--longs);
    }
    #endif
    void MD5Init(ctx)struct MD5Context *ctx;
    {
        ctx->buf[0] = 0x67452301;
        ctx->buf[1] = 0xefcdab89;
        ctx->buf[2] = 0x98badcfe;
        ctx->buf[3] = 0x10325476;
        ctx->bits[0] = 0;
        ctx->bits[1] = 0;
    }
    void MD5Update(ctx, buf, len) struct MD5Context *ctx; unsigned char *buf; unsigned len;
    {
        uint32 t;
        t = ctx->bits[0];
        if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
        ctx->bits[1]++;
        ctx->bits[1] += len >> 29;
        t = (t >> 3) & 0x3f;
        if (t) {
        unsigned char *p = (unsigned char *) ctx->in + t;
        t = 64 - t;
        if (len < t) {
            memcpy(p, buf, len);
            return;
        }
        memcpy(p, buf, t);
        byteReverse(ctx->in, 16);
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        buf += t;
        len -= t;
        }
        while (len >= 64) {
        memcpy(ctx->in, buf, 64);
        byteReverse(ctx->in, 16);
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        buf += 64;
        len -= 64;
        }
        memcpy(ctx->in, buf, len);
    }
    void MD5Final(digest, ctx)
        unsigned char digest[16]; struct MD5Context *ctx;
    {
        unsigned count;
        unsigned char *p;
        count = (ctx->bits[0] >> 3) & 0x3F;
        p = ctx->in + count;
        *p++ = 0x80;
        count = 64 - 1 - count;
        if (count < 8) {
        memset(p, 0, count);
        byteReverse(ctx->in, 16);
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        memset(ctx->in, 0, 56);
        } else {
        memset(p, 0, count - 8);
        }
        byteReverse(ctx->in, 14);
        ((uint32 *) ctx->in)[14] = ctx->bits[0];
        ((uint32 *) ctx->in)[15] = ctx->bits[1];
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        byteReverse((unsigned char *) ctx->buf, 4);
        memcpy(digest, ctx->buf, 16);
        memset(ctx, 0, sizeof(ctx));
    }
    #define F1(x, y, z) (z ^ (x & (y ^ z)))
    #define F2(x, y, z) F1(z, x, y)
    #define F3(x, y, z) (x ^ y ^ z)
    #define F4(x, y, z) (y ^ (x | ~z))
    #define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
    void MD5Transform(buf, in)
        uint32 buf[4]; uint32 in[16];
    {
        register uint32 a, b, c, d;
        a = buf[0];
        b = buf[1];
        c = buf[2];
        d = buf[3];
        MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
        MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
        MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
        MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
        MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
        MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
        MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
        MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
        MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
        MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
        MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
        MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
        MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
        MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
        MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
        MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
        MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
        MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
        MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
        MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
        MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
        MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
        MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
        MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
        MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
        MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
        MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
        MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
        MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
        MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
        MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
        MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
        MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
        MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
        MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
        MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
        MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
        MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
        MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
        MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
        MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
        MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
        MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
        MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
        MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
        MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
        MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
        MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
        MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
        MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
        MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
        MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
        MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
        MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
        MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
        MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
        MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
        MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
        MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
        MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
        MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
        MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
        MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
        MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
        buf[0] += a;
        buf[1] += b;
        buf[2] += c;
        buf[3] += d;
    }
    char* CMd5(const char* s)
    {
         struct MD5Context md5c;
         unsigned char ss[16];
         char subStr[3],resStr[33];
         int i;
         MD5Init( &md5c );
         MD5Update( &md5c, s, strlen(s) );
         MD5Final( ss, &md5c );
         strcpy(resStr,"");
         for( i=0; i<16; i++ )
         {
             sprintf(subStr, "%02x", ss[i] );
             itoa(ss[i],subStr,16);
             if (strlen(subStr)==1) {
                 strcat(resStr,"0");
             }
             strcat(resStr,subStr);
         }
         strcat(resStr,"\0");
         return resStr;
    }
    在Action测试调用一下
    Action:
    Action()
    {
       
        lr_output_message(CMd5("1234561"));

        return 0;
    }
  • EJB性能测试步骤整理

    2012-06-08 17:37:08

    1.       主要业务性能指标(从业务角度上分析,例如查询,修改,表单提交)

    2.       统计EJB访问量,根据28原则

    3.       性能负载级别,达到多少才算合理

    4.       系统稳定性

    5.       根据EJB实现对业务的分析

    6.       明确测试目的

    7.       测试用例整理

    8.       测试场景设置

    9.       测试指标及其标准

    10.   测试数据的准备

    11.   负载测试、稳定性测试

  • http协议

    2012-06-06 15:35:42

    HTTP/1.1协议中共定义了八种方法(有时也叫“动作”)来表明Request-URI指定的资源的不同操作方式:   
    OPTIONS 返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送'*'的请求来测试服务器的功能性。    
    HEAD
    向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。    
    GET 向特定的资源发出请求。注意:GET方法不应当被用于产生“副作用”的操作中,例如在web app.中。其中一个原因是GET可能会被网络蜘蛛等随意访问。    
    POST
    向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。    
    PAT 向指定资源位置上传其最新内容。    
    DELETE
    请求服务器删除Request-URI所标识的资源。    
    TRACE 回显服务器收到的请求,主要用于测试或诊断。    
    CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
  • LoadRunner常见测试结果分析(转)

    2012-06-06 10:59:36

    在测试过程中,可能会出现以下常见的几种测试情况:

      一、当事务响应时间的曲线开始由缓慢上升,然后处于平衡,最后慢慢下降这种情形表明:

      * 从事务响应时间曲线图持续上升表明系统的处理能力在下降,事务的响应时间变长;

      * 持续平衡表明并发用户数达到一定数量,在多也可能接受不了,再有请求数,就等待;

      * 当事务的响应时间在下降,表明并发用户的数量在慢慢减少,事务的请求数也在减少。

      如果系统没有这种下降机制,响应时间越来越长,直到系统瘫痪。

      从以上的结果分析可发现是由以下的原因引起:

      1. 程序中用户数连接未做限制,导致请求数不断上升,响应时间不断变长;

      2. 内存泄露;

      二、CPU的使用率不断上升,内存的使用率也是不断上升,其他一切都很正常;

      表明系统中可能产生资源争用情况;

      引起原因:

      开发人员注意资源调配问题。

      三、 所有的事务响应时间、cpu等都很正常,业务出现失败情况;

      引起原因:

      数据库可能被锁,就是说,你在操作一张表或一条记录,别人就不能使用,即数据存在互斥性;

      当数据量大时,就会出现数据错乱情况。
  • loadrunner监控webservice方案

    2012-04-24 10:42:20

    1.直接选择webservice协议录制脚本
    2.选择manage services ,然后点import。
    3.在弹出的框中输入你要测试的webservice的URL
    例如:http://**/**/services/MbrPasswordService?wsdl这种样式的。点import,导入成功点OK结束
    4.然后点Add Services Call 在service下点import service,然后选择你的operation对象,选择portname,然后参数你的input arguments值,点OK直接可以
    生成webservice脚本了!
    (因为无法截图,悲剧大家有问题可以直接QQ我)
  • 性能测试监控EJB

    2012-04-24 10:38:04

    使用loadrunner监控EJB可以分为监控EJB客户端,或监控EJB服务端。
    监控EJB客户端直接在loadrunner中采用java vuser协议就可以,
    引入JVM,引入客户端jar,直接调用EJB客户端对外接口实现的方法就行。
  • 读取文件的一些函数C相关(美女妹妹收集)

    2012-04-20 17:02:29

    Fopen函数:

    在打开一个文件时,如果出错,fopen将返回一个空指针值NULL

    文件指针名=fopen(文件名,使用文件方式);

    其中:

    文件指针名必须是被说明为FILE 类型的指针变量;

    文件名是被打开文件的文件名;

    使用文件方式是指文件的类型和操作要求。

    文件名是字符串常量或字符串数组

    void *calloc(unsigned n,unsigned size)

    功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL

    malloc的区别:

    calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。

    feof(fp)有两个返回值:如果遇到文件结束,函数feoffp)的值为非零值,否则为0

    void *realloc(void *mem_address, unsigned int newsize);

    语法:指针名=(数据类型*realloc(要改变内存大小的指针名,新的大小)。//新的大小一定要大于原来的大小不然的话会导致数据丢失!

    fread

    功 能: 从一个流中读数据

    函数原型: size_t fread(void*buffer,size_tsize,size_tcount,FILE*stream); 

    参 数:

    1.用于接收数据的地址(指针)(buffer

    2.单个元素的大小(size) :单位是字节而不是位,例如读取一个int型数据就是4个字节

    3.元素个数(count

    4.提供数据的文件指针(stream

    返回值:读取的元素的个数

    fclose()

    功 能: 关闭一个流。注意:使用fclose()函数就可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区。

  • 系统性能调优

    2012-04-20 11:46:33

    1.硬件问题
    2.网络问题
    3.应用服务器、数据库等配置问题
    4.源代码、数据库脚本问题
    5.系统架构问题
    策略:按照上述由易到难的顺序对系统进行调优
  • 为什么要用多台虚拟机进行压力测试

    2012-04-20 11:26:03

    1.首先无论以线程方式还是以进程方式跑都会占服务器内存的,如果内存满了就很难达到性能测试的目的。
    2.有些会做IP限制,也许是客户端本身做了限制,有些是服务器端做了限制同一IP重复发多次请),这些地方要具体分析。
    3.其实多台虚拟的也能更好模拟真实用户环境不是。
  • 20-80原则

    2012-04-20 11:12:04

    根据20-80原则,通常系统用户经常使用的功能模块大概占用系统整个功能模块数目的20%
  • loadrunner监控EJB(1)

    2012-04-18 15:11:04

    1.直接使用loadrunner监控EJB说起来容易,其实实现起来还是很有点复杂。
    刚好这次公司有这个机会可以学习一下loadrunner监控EJB。看到网上写的方法千篇一律我都奇怪了,那么多人发的都是
    同样的话,同样的解决方案,连监控的EJB对象都是一样的。这是咋做的!悲剧中!
    2.没办法自己相办法吧!首先根据开发提供了一个方案,我这边写了一个工程,实现JSP+SEVERLET+JAVA来调EJB的客户端。写完后部署上去,发现可以实现。不失为一个好方法!但是对于不了解代码的人来说比较难了!
    3.后来老大要求loadrunner可以实现直接对EJB的监控!又是一个痛苦的历程啊,经过三天的努力终于实现!
    下面就把如何实现的过程分享一下:
    1.首先部署EJB监控器到服务器上,我使用的是单机环境(websphere+linux环境),在loadrunner里面找到ejbdetector.jar然后上传到服务器上,解压后配置环境变量(env.sh)(解压命令:jar -xvf jar包名称)
    环境变量配置如下:
    JAVA_HOME=/**/WebSphere/AppServer/java; export JAVA_HOME (java编译环境)
    DETECTOR_INS_DIR=/home/was1; export DETECTOR_INS_DIR(ejbdetector的安装路径)
    APP_SERVER_ROOT=/**/WebSphere/AppServer; export APP_SERVER_ROOT(was服务路径)
    EJB_DIR_LIST=/**/installedApps/wasdev-001Node01Cell(EJB应用安装路径)
    (忙了,先干活ing)


  • loadrunner监控EJB

    2012-04-16 11:05:04

    关于EJB的监控直接使用loadrunner监控比较麻烦,我想了一个简单的办法来实现监控EJB,我写了一个JSP通过jsp页面来调后台的EJB,这样我们loadrunner直接录制http协议的脚本即可!
    (jsp-severlet-class实现调用EJB)
  • 查看本地进程以及查看远程计算机进程

    2012-04-10 10:22:49

    1.查看本地进程相关信息
    通过访问CMD,输入tasklist/?来查看帮助信息
    输入如:tasklist运行结果显示运行在本地或远程计算机上的所有任务的应用程序和服务列表
    输入如:tasklist/m |more进行分页显示所有进程模块信息
    2.查看远程计算机上的所有任务的应用程序和服务列表
    输入如:tasklist /s 远程电脑ip /u 远程电脑用户名/p 远程电脑密码
  • 线程和进程运行的方式有何不同

    2012-04-09 16:38:45

    1.怎么设置如何使用线程跑或进程跑
    【Vuser】 >【Run-Time Setting...】>【Multithreading】中选择设置
    2.如果按进程运行每个vuser,则对于每个Vuser实例,都将反复启动同一程序并将其加载到内存中。这样会占用大量的RAM及其它系统资源。这就限制了任一负载生成器上运行的Vuser的数量。如果按线程运行每个Vuser,Controller为每50个Vuser仅启动驱动程序的一个实例。该驱动进程/程序将启动几个Vuser,每个Vuser都按线程运行。这些线程Vuser将共享父驱动进程的内存段。这就消除了多次重新加载驱动程序/进程的需要,节省了大量内存空间,进而可以在负载生成器上运行更多的Vuser。
    注意:
    下列协议不是线程安全协议,如Sybase-Ctilib,Sybase-Dblib,Informix,Tuxedo
    and PeopleSoft-Tuxedo.
  • loadrunner11关联

    2012-04-09 10:15:24

    1.什么是关联
    关联就是把脚本中写死的数据,转变成动态数据来适应脚本的方式。
    2.为什么要关联
    几种原因,我个人任务如下几点:
    1.网站想服务器发送请求标示,例如sessionID如果不转成动态就跑不通过
    2.关联可以使用伪数据来解决无法性能测试的方案。
    3.具体该怎样关联
    自动关联就不多说,手动关联才是王道!
    我个人觉得比较简单,直接同样的请求,同样的数据重复录制两次,
    然后使用loadrunner中的Windiff比较就可以!
    选择【tools】>【Compare with Vuser】然后选择要比较脚本既可,
    弹出黄色部分内容为有差异的代码行!
  • 关于loadrunner弹出错误not writing pre_cci.ci

    2012-04-06 11:36:57

    关于loadrunner弹出错误not writing pre_cci.ci
    主要原因都是由于编译不通过的错误导致。
    例如:
     float r = 4.5;
     float s;
     double r1 = 22.36;
     double s1;
     long double r2 = 876.99;
     long double s2;
      
     s = PI * r * r;
     s1 = PI * r1 * r1;
     s2 = PI * r2 * r2;
     int total=0;
      total = id *mount;
       lr_output_message("mianjiis:%d",total);
       lr_output_message("mainjiis:%f",s);
    输出报错,想了半天最后终于找到原因,这个属于C的基本语法规则,必须把定义
    放在前面,把算法放后面,不能交叉定义!
    实际结果如下:
     int total=0; 
     float r = 4.5;
     float s;
     double r1 = 22.36;
     double s1;
     long double r2 = 876.99;
     long double s2;
        total = id *mount;
     s = PI * r * r;
     s1 = PI * r1 * r1;
     s2 = PI * r2 * r2;
       lr_output_message("mianjiis:%d",total);
       lr_output_message("mainjiis:%f",s);
     
Open Toolbar