想到 与 得到 之间,要做到

发布新日志

  • 转Linux性能监控笔记

    2012-02-29 17:05:57

    原文地址:
    http://17610376.blog.51cto.com/366886/495836

    第 1 章 概述篇
    针对四大方向
    CPU
    Memory
    IO
    Network
    基本参考标准
    # vmstat 1
    procs   memory         swap          io        system         cpu
    r  b   swpd   free   buff  cache     si   so    bi    bo     in    cs us sy wa id
    1  0 138592  17932 126272 214244    0    0     1    18    109    19  2  1  1 96
    0  0 138592  17932 126272 214244    0    0     0     0    105    46  0  1  0 99
     
     
    安装监控工具  yum -y install sysstat
    表 1.1. 监控系统性能工具
    安装监控工具  yum -y install sysstat
    表 1.1. 监控系统性能工具Tool
    Description
    Base
    Repository
    vmstat
    all purpose performance tool
    yes
    yes
    mpstat
    provides statistics per CPU
    no
    yes
    sar
    all purpose performance monitoring tool
    no
    yes
    iostat
    provides disk statistics
    no
    yes
    netstat
    provides network statistics
    yes
    yes
    dstat
    monitoring statistics aggregator
    no
    in most distributions
    iptraf
    traffic monitoring dashboard
    no
    yes
    netperf
    Network bandwidth tool
    no
    In some distributions
    ethtool
    reports on Ethernet interface configuration
    yes
    yes
    iperf
    Network bandwidth tool
    no
    yes
    tcptrace
    Packet analysis tool
    no
    yes
    strace
    查看相关进程读写的数据


    第 2 章 CPU篇
    CPU调度优先级
    Interrupts(中断)高于Kernel(System) Processes(内核处理过程)高于User Processes(用户进程)
    上下文切换
    Linux 内核的系统在一个双核心处理器上,是报告显示为两个独立的处理器.
    一个线程要么就是获得时间额度或已抢先获得一些具有较高优先级(比如硬件中断),其中较高优先级的线程将从区域重新放置回处理器的队列中.这种线程的转换关系就是我们提到的上下文切换.
    每次内核的上下文切换,资源被用于关闭在CPU寄存器中的线程和放置在队列中.系统中越多的上下文切换,在处理器的调度管理下,内核将得到更多的工作.
    运行队列
    每个CPU 都维护一个线程的运行队列
    CPU 利用率
    User Time(译注:用户进程时间)
    System Time(译注:内核线程以及中断时间)
    Wait IO(译注:IO 请求等待时间)
    Idle(译注:空闲)
    CPU 性能监控
    Run Queues - 每个处理器应该运行队列不超过1-3个线程.
    Run Queues - 每个处理器应该运行队列不超过1-3个线程.例子,一个双核处理器应该运行队列不要超过6 个线程。
    CPU Utiliation - 如果一个CPU 被充分使用,利用率分类之间均衡的比例应该是:
    65% - 70% User Time
    30% - 35% System Time
    0% - 5%   Idle Time
    Context Switches - 上下文切换的数目直接关系到CPU 的使用率,如果CPU 利用率保持在上述均衡状态时,大量的上下文切换是正常的.
    vmstat 工具的使用
    vmstat 运行1秒间隔的示例:
    # vmstat 1
    procs ———–memory———- —swap– —–io—-  –system–        —-cpu—-
    r  b   swpd   free   buff  cache        si      so    bi    bo   in    cs us sy id wa
    0  0 104300  16800  95328  72200    0    0     5    26    7    14  4  1 95  0
    0  0 104300  16800  95328  72200    0    0     0    24 1021    64  1  1 98  0
    0  0 104300  16800  95328  72200    0    0     0     0 1009    59  1  1 98  0
     
    Field
    Description
    r
    The amount of threads in the run queue. These are threads that are runnable, but the CPU is not available to execute them. 当前运行队列中线程的数目.代表线程处于可运行状态,CPU 还未能执行.
    b
    This is the number of processes blocked and waiting on IO requests to finish. 当前进程阻塞并等待IO 请求完成的数目
    in
    This is the number of interrupts being processed. 当前中断被处理的数目
    cs
    This is the number of context switches currently happening on the system. 当前kernel system,发生上下文切换的数目
    us
    This is the percentage of user CPU utilization. CPU 利用率的百分比
    sys
    This is the percentage of kernel and interrupts utilization. 内核和中断利用率的百分比
    wa
    This is the percentage of idle processor time due to the fact that ALL runnable threads are blocked waiting on IO. 所有可运行状态线程被阻塞在等待IO 请求的百分比
    id
    This is the percentage of time that the CPU is completely idle. CPU 空闲时间的百分比
     
     
    mpstat 工具的使用
    mpstat 命令给出的CPU 利用率统计值大致和 vmstat 一致,但是 mpstat 可以给出基于单个处理器的统计值.
    # mpstat –P ALL 1
    Linux 2.4.21-20.ELsmp (localhost.localdomain)   05/23/2006
    05:17:31 PM  CPU   %user   %nice %system   %idle    intr/s
    05:17:32 PM  all    0.00    0.00    3.19   96.53     13.27
    05:17:32 PM    0    0.00    0.00    0.00  100.00      0.00
    05:17:32 PM    1    1.12    0.00   12.73   86.15     13.27
    05:17:32 PM    2    0.00    0.00    0.00  100.00      0.00
    05:17:32 PM    3    0.00    0.00    0.00  100.00      0.00
    第 3 章 内存篇
    Virtual Memory Pages 在X86架构中,每个虚拟内存页为 4KB。
    内存分页是指内核会定期将内存中的数据同步到硬盘,这个过程就是Memory Paging。
    PFRA 就是OS 内核用来回收并释放内存空间的算法.PFRA 选择哪个内存页被释放是基于内存页类型的.页类型有以下几种:
    Unreclaimable –锁定的,内核保留的页面
    Swappable –匿名的内存页
    Syncable –通过硬盘文件备份的内存页
    Discardable –静态页和被丢弃的页
    除了第一种(Unreclaimable)之外其余的都可以被PFRA进行回收.
    kswapd
    kswapd 进程负责确保内存空间总是在被释放中.它监控内核中的pages_high和pages_low阀值.如果空闲内存的数值低于 pages_low,则每次 kswapd 进程启动扫描并尝试释放32个free pages.并一直重复这个过程,直到空闲内存的数值高于 pages_high.
    kswapd 进程完成以下几个操作:
    如果该页处于未修改状态,则将该页放置回空闲列表中。
    如果该页处于已修改状态并可备份回文件系统,则将页内容写入到磁盘。
    如果该页处于已修改状态但没有任何磁盘备份,则将页内容写入到swap device。
    第 4 章 IO篇
    磁盘I/O 子系统是Linux 系统中最慢的部分
    Linux 内核就是要最低程度的降低I/O 数.
    # /usr/bin/time -v date
    Linux,类似多数的UNIX 系统,使用一个虚拟内存层来映射硬件地址空间.当一个进程被启动,内核先扫描CPU caches和物理内存.如果进程需要的数据在这2个地方都没找到,就需要从磁盘上读取,此时内核过程就是major page fault(MPF).MPF 要求磁盘子系统检索页并缓存进RAM.
    一旦内存页被映射进内存的buffer cache(buff)中,内核将尝试从内存中读取或写入,此时内核过程就是minor page fault(MnPF).与在磁盘上操作相比,MnPF 通过反复使用内存中的内存页就大大的缩短了内核时间.
    在Linux 内核中,memory pages有3种,分别是:
    1,Read Pages - 这些页通过MPF 从磁盘中读入,而且是只读.这些页存在于Buffer Cache中以及包括不能够修改的静态文件,二进制文件,还有库文件.当内核需要它们时,将读取到内存中.如果内存不足,内核将释放它们回空闲列表中.程序再次请求时,则通过MPF 再次读回内存.
    2,Dirty Pages - 这些页是内核在内存中已经被修改过的数据页.当这些页需要同步回磁盘上,由pdflush 负责写回磁盘.如果内存不足,kswapd (与pdflush 一起)将这些页写回到磁盘上并释放更多的内存.
    3,Anonymous Pages - 这些页属于某个进程,但是没有任何磁盘文件和它们有关.他们不能和同步回磁盘.如果内存不足,kswapd 将他们写入swap 分区上并释放更多的内存(”swapping” pages).
    监控 I/O
    每个I/O 请求到磁盘都需要若干时间.主要是因为磁盘的盘边必须旋转,机头必须寻道.磁盘的旋转常常被称为”rotational delay”(RD),机头的移动称为”disk seek”(DS).一个I/O 请求所需的时间计算就是DS加上RD.磁盘的RD 基于设备自身RPM 单位值(译注:RPM 是Revolutions Perminute的缩写,是转/每分钟,代表了硬盘的转速).一个RD 就是一个盘片旋转的半圆.如何计算一个10K RPM设备的RD 值呢:
    10000 RPM / 60 seconds (10000/60 = 166 RPS)
    转换为 166分之1 的值(1/166 = 0.006 seconds/Rotation)
    单位转换为毫秒(6 MS/Rotation)
    旋转半圆的时间(6/2 = 3MS) 也就是 RD
    加上平均3 MS 的寻道时间 (3MS + 3MS = 6MS)
    加上2MS 的延迟(6MS + 2MS = 8MS)
    1000 MS / 8 MS (1000/8 = 125 IOPS)
    每次应用程序产生一个I/O,在10K RPM磁盘上都要花费平均 8MS.在这个固定时间里,磁盘将尽可能且有效率在进行读写磁盘.IOPS 可以计算出大致的I/O 请求数,10K RPM 磁盘有能力提供120-150 次IOPS.评估IOPS 的效能,可用每秒读写I/O 字节数除以每秒读写IOPS 数得出.
    结论
    当CPU 有等待I/O 情况时,那说明磁盘处于超负荷状态.
    计算你的磁盘能够承受多大的IOPS 数.
    确定你的应用是属于随机或者顺序读取磁盘.
    监控磁盘慢需要比较wait time(await) 和 service time(svctm).
    监控swap 和系统分区,要确保virtual memory不是文件系统I/O 的瓶颈.
    第 5 章 网络(Network)篇
    iptraf 工具(http://iptraf.seul.org),提供了每个网卡吞吐量的仪表盘.
    #iptraf -d eth0
    图 5.1. Monitoring for Network Throughput
     
    案例学习 - 性能监控之循序渐进
    # vmstat 1 10
    procs memory swap io system cpu
    r b swpd free buff cache si so bi bo in cs us sy id wa
    1 0 249844 19144 18532 1221212 0 0 7 3 22 17 25 8 17 18
    0 1 249844 17828 18528 1222696 0 0 40448 8 1384 1138 13 7 65 14
    0 1 249844 18004 18528 1222756 0 0 13568 4 623 534 3 4 56 37
    2 0 249844 17840 18528 1223200 0 0 35200 0 1285 1017 17 7 56 20
    分析:
    不会是内存不足导致,因为swapping 始终没变化(si 和 so).尽管空闲内存不多(free),但swpd 也没有变化.
    CPU 方面也没有太大问题,尽管有一些运行队列(procs r),但处理器还始终有50% 多的idle(CPU id).
    有太多的上下文切换(cs)以及disk block从RAM中被读入(bo).
    CPU 还有平均20% 的I/O 等待情况.
    从以上总结出,这是一个I/O 瓶颈.
    # iostat -x 1
    Linux 2.4.21-40.ELsmp (mail.example.com) 03/26/2007
    avg-cpu: %user %nice %sys %idle
    30.00 0.00 9.33 60.67

    Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
    /dev/sda 7929.01 30.34 1180.91 14.23 7929.01 357.84 3964.50 178.92 6.93 0.39 0.03 0.06 6.69
    /dev/sda1 2.67 5.46 0.40 1.76 24.62 57.77 12.31 28.88 38.11 0.06 2.78 1.77 0.38
    /dev/sda2 0.00 0.30 0.07 0.02 0.57 2.57 0.29 1.28 32.86 0.00 3.81 2.64 0.03
    /dev/sda3 7929.01 24.58 1180.44 12.45 7929.01 297.50 3964.50 148.75 6.90 0.32 0.03 0.06 6.68

    分析:
    看上去只有/dev/sda3 分区很活跃,其他分区都很空闲.
    差不多有1200 读IOPS,磁盘本身是支持200 IOPS左右(译注:参考之前的IOPS 计算公式).
    有超过2秒,实际上没有一个读磁盘(rkb/s).这和在vmstat 看到有大量I/O wait是有关系的.
    大量的read IOPS(r/s)和在vmstat 中大量的上下文是匹配的.这说明很多读操作都是失败的.
    结论:
    从以上总结出,部分应用程序带来的读请求,已经超出了I/O 子系统可处理的范围.
    使用top 来查找系统最活跃的应用程序
    # top -d 1
    11:46:11 up 3 days, 19:13, 1 user, load average: 1.72, 1.87, 1.80
    176 processes: 174 sleeping, 2 running, 0 zombie, 0 stopped
    CPU states: cpu user nice system irq softirq iowait idle
    total 12.8% 0.0% 4.6% 0.2% 0.2% 18.7% 63.2%
    cpu00 23.3% 0.0% 7.7% 0.0% 0.0% 36.8% 32.0%
    cpu01 28.4% 0.0% 10.7% 0.0% 0.0% 38.2% 22.5%
    cpu02 0.0% 0.0% 0.0% 0.9% 0.9% 0.0% 98.0%
    cpu03 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 100.0%
    Mem: 2055244k av, 2032692k used, 22552k free, 0k shrd, 18256k buff
    1216212k actv, 513216k in_d, 25520k in_c
    Swap: 4192956k av, 249844k used, 3943112k free 1218304k cached
    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    14939 mysql 25 0 379M 224M 1117 R 38.2 25.7% 15:17.78 mysqld
    4023 root 15 0 2120 972 784 R 2.0 0.3 0:00.06 top
    1 root 15 0 2008 688 592 S 0.0 0.2 0:01.30 init
    2 root 34 19 0 0 0 S 0.0 0.0 0:22.59 ksoftirqd/0
    3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
    4 root 10 -5 0 0 0 S 0.0 0.0 0:00.05 events/0
    从以上总结出,似乎就只有mysql 进程在请求资源,因此可以推论它就是导致问题的关键.
    现在已经确定是mysql 在发出读请求,使用strace 来检查它在读请求什么.
    # strace -p 14939
    Process 14939 attached - interrupt to quit
    read(29, “\3\1\237\1\366\337\1\222%\4\2\0\0\0\0\0012P/d”, 20) = 20
    read(29, “ata1/strongmail/log/strongmail-d”…, 399) = 399
    _llseek(29, 2877621036, [2877621036], SEEK_SET) = 0
    read(29, “\1\1\241\366\337\1\223%\4\2\0\0\0\0\0012P/da”, 20) = 20
    read(29, “ta1/strongmail/log/strongmail-de”…, 400) = 400
    从以上总结出,所有的读IOPS 都是mysql 进程在执行某些读查询时产生的.
    使用mysqladmin 命令,来查找是哪个慢查询导致的.
    # ./mysqladmin -pstrongmail processlist
    +—-+——+———–+————+———+——+———-+—————————————-
    | Id | User | Host | db | Command | Time | State | Info
    +—-+——+———–+————+———+——+———-+—————————————-
    | 1 | root | localhost | strongmail | Sleep | 10 | |
    | 2 | root | localhost | strongmail | Sleep | 8 | |
    | 3 | root | localhost | root | Query | 94 | Updating | update `failures` set
    `update_datasource`=’Y’ where database_id=’32′ and update_datasource=’N’ and |
    | 14 | root | localhost | | Query | 0 | | show processlist
    分析:
    MySQL 数据库里,似乎在不断的运行table update查询.
    基于这个update 查询,数据库是对所有的table 进行索引.
    结论:
    从以上总结出,MySQL里这些update 查询问题,都是在尝试对所有table 进行索引.这些产生的读请求正是导致系统性能下降的原因.
  • javaVuser测试Mysql注意事项

    2011-12-31 10:53:55

    通过javaVuser协议,测试mysql时,需要在LR中导入mysql_jdbc.jar。这个jar包必须要放在脚本目录中,否则运行脚本时会抛java.lang.ClassNotFoundException: com.mysql.jdbc.Driver异常。

    特此记录,以备后用!
  • LoadRunner监控Linux中Paging rate转换为内存使用率

    2011-11-18 16:24:04

    最近做了一个项目,用LoadRunner监控内存使用率,Paging Rate这个指标官方解释为:Number of pages read to physical memory or written to
    pagefile(s), per second
    但是它具体使用了多大内存呢?请教高人后,在被监控系统(Linux)中使用这个命令:
    getconf PAGESIZE。可以得到一个内存分页的大小(Kbyte)。这样就可以计算出内存使用率了。

    一家之谈,不足为证。欢迎拍砖!!!
  • LoadRunner调用md5方法

    2011-04-29 11:25:12

    有个项目的请求参数中,有一个参数需要md5加密。在google搜索了些LR调用MD5方法的资料。参考资料实现了参数md5加密。现将方法做下总结:

    1.首先将md5算法在C编译器中生成md5.h文件,在Vuser generator中添加这个md5.h文件,然后再global.h中添加#include "md5.h"头文件

    2.调用md5方法:lr_output_message("%s",CMd5("test"))

    ---也可以将md5方法生成dll,然后在LR中调用这个DLL。(此方法没有尝试过)

    md5方法如下:

    #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;
    }

  • Free命令中-/+ buffers/cache的理解

    2011-04-18 16:21:41

    我在linux中输入free命令时,会显示如下信息(红色字体):
                 total       used       free     shared    buffers     cached
    Mem:        506916     499708       7208          0     149868     247556
    -/+ buffers/cache:     102284     404632
    Swap:      1052216          0    1052216

    红色部分中:
    -buffers/cache = used - buffer - cache

    + buffers/cache = free + buffer + cache


    所以used下面第2行(-buffers/cache)表示一共已经使用的内存,free下面的第2行(+buffers/cache)表示一共可用内存。
  • LR中平均响应时间&90%Percent时间理解

    2010-08-30 23:36:00

        平均响应时间与90%Percent时间这两个名词的计算方法不是很清楚。在公司的时候跟同事争论了半天,也没有个最终结果。下班回来做了个实验,把大致内容做了个总结,如下:

        1.平均响应时间:录制了一个LR自带订票的登录操作,给登录加了一个事物。在场景中设置5个vuser,运行1分钟。运行结束后,导入analysis中。平均响应时间图中,把表中的Raw Data数据中的登录事物的响应时间copy到excel中,算出它的平均值。结果与图表中的平均值是一样的。只是平均响应时间图中只把Raw Data中的最大、最小、平均值列出来了。

        2.90%Percent:首先,analysis中的Transaction Percentile改成100%。场景运行完后(沿用login的脚脚本),把运行结果导入analysis中。对比Summary报告中的100%Percent值与Raw Data中最大值是否一致。实践证明是完全一致的。根据这个结果,我可以推断出90%Percent是先将响应时间由大到小排序(假设有10个响应时间,1s,2s,3s,4s,5s,6s,7s,8s,9s,10s),然后去掉最大的响应时间(10s),取9s作为90% Percent时间。同理80%、70%。。。都是按照这个模式来计算的。

    这里我还有2个疑问:

    1.比如:1,1,3,10,2这样一组响应时间,最小、最大响应时间的差距很大,按照LR的计算方式等于3.4。个人觉得如果响应时间分布不是很均匀,这个算法就不太合理了。应该去掉一个最大值和一个最小值,再去求平均值(就跟电视中评委打分一样)。不知道这个方法是否可行,在这里提出来跟大家共同探讨!

    2.平均响应时间图标中每个时间点的间隔时间都不一致,曲线的时间点是如何计算出来的?

    总结的差不多了,希望跟大家共同探讨响应时间的问题。其中可能会有总结不正确、不充分的地方。还请大家帮忙指正!

    欢迎拍砖!!!

  • 一个bug引起的反思

    2010-06-30 23:26:21

        测试能否发现全部bug呢?答案是否定的。但是,测试可以尽早发现bug。这样不会影响测试进度,确保系统按期上线。今天我是深深的感觉到尽早发现bug是多么的重要。

        事情是这样的,最近测试了一个项目,今天是第二轮测试。如果通过的话,就能上线了,测试过程中提交了1个bug。下午,开发打电话问我这个bug是如何重现的(后来交谈中得知开发只是拿这个当话题),我就一步步描述了这个步骤。开发听完后,跟我说:“为什么上一轮测试没有发现这个问题呢?”听完顿时一愣,是呀!上一轮测试怎么没发现呢。我说抱歉,可能遗漏了测试。这哥们挺大读地说:没关系,最好在第一轮多发现问题,这样不影响上线的时间,我们也好跟领导交代。另外,我们也有绩效。打完电话后,我心里没有抱怨开发,而是让我对之前的工作进行了反思,他的这句话有点一语惊醒梦中人的感觉,让我认识到自己在测试工作中的不足。跟原来公司的开发在msn聊天,他说提前发现bug,避免我们重写方法,减少改动。下班回来仔细想了想,测试之前写的用例覆盖范围不够,测试不够细致(虽然,刚去这个新公司,业务不太了解。但是这个借口也比较傲勉强)。没有去深入的挖掘逻辑业务。在第一轮测试结束后,没有再去思考哪些功能或者场景没有覆盖到。虽然,测试不能找到全部的bug,但是可以尽早去发现它。在固定的项目进度中,第一轮的测试最为重要,测试一定要细致,尽可能多的去发现问题,尽量不要遗留高优先级的bug(不排除开发修改bug引起新的bug),不然等到后续测试中总是出现阻碍上线的bug,导致增加测试轮次或者带着bug仓促上线,这些都是我们不希望的。

        事情虽然过去,我要吸取经验教训,在以后的测试中,尽可能的去补充及完善用例,多从业务层面去挖掘潜在的bug,不让同样的问题再次发生。^_^

        再次感谢那位开发哥们儿的宽容!

  • [论坛] [我和51Testing]51testing 我测试人生路上的好朋友!!!

    2010-04-29 16:16:08

         3年前我接触了软件测试这个行业,同时通过网络了解了你———51testing!感谢你们给测试同行们提供了一个交流、技术分享的平台,大家在论坛区交流心得,分享技术经验,共同提高、共同进步。
        从论坛、到每日话题、再到定期举办的软件沙龙,51testing逐步完善、扩大测试平台规模及范围,而这些活动对我的测试工作提供了很大的帮助。每当遇到技术问题,我都会来论坛去找解决方案或寻求帮助。现在每天浏览51testing已经成为我生活的一部分。感谢51testing默默地一路相伴!!!

        借此51testing成立六周年之际,谨代表在51testing获得过帮助的测试同行们,祝愿51testing这个平台越办越好!


    [ 本帖最后由 亚瑟王 于 2010-4-29 16:16 编辑 ]
  • 性能测试方法(转)

    2008-09-22 15:20:18

    上周六参加了3Atesting的网络沙龙,会后感觉受益匪浅。学习性能测试首先应该从方法入手,故今天就在51testing中搜索到一篇关于性能测试方法的文章。与大家分享

    http://www.51testing.com/html/8/653.html

  • 转一篇面试经验总结

    2008-09-01 16:30:10

  • 修改LR参数化时,显示的参数的行数

    2008-07-30 23:22:34

    1、先找到VUGEN.ini应该在c:\windows目录下
    2、然后修改MaxVisibleLines参数,输入你要求的显示行数
  • linux虚拟机访问本机Windows共享文件设置方法

    2008-07-25 15:32:01

    第一步:打开虚拟机 点vm-----install vmtools

    第二步:
    1.运行虚拟机Linux,切换到图形界面;

    2.  1)查看光驱是否已挂载,mount /dev/cdrom /mnt/cdrom;
        2)cp /mnt/cdrom/VMwareTools-6.0.0-45731.tar.gz /usr/tmp
       3)cd /usr/tmp
       4)tar -xzvf VMwareTools-6.0.0-45731.tar.gz
        5)cd vmware-tools-distrib
        6)./vmware-install.pl (一路回车,等看到Enjoy Vmtools,成功。)

    第三步:配置共享文件夹 vm-----settings--options 双击shared folders,在旁边添加文件夹,并选择always enable

    第四步:进入Linux中,在/mnt目录中,查看是否有hgfs这个文件夹。如果有就表示windows共享文件夹添加成功

Open Toolbar