希望认识做性能测试的朋友,共同学习提高。

发布新日志

  • 如何录制仿真终端的ESC键

    2010-03-04 15:13:13

    最近在测一个字符终端的程序,在录制时"ESC"取消键总是录制不上,费了很大的劲,才有朋友告知要用“CTRL+[”符合,因为仿真终端是用这个组合键来代替“ESC”键的。
  • 软件设计是决定软件性能的关键

    2009-10-03 12:02:43

    这是我的一篇老帖子,在一次偶然的搜索中,从另外一个人的博客中发现了,呵呵,尽然没有看出是自己的帖子,所以在这里重发一下。

    做 测试有较长的时间了,在各个测试论坛中也潜水了很长时间,主要是比较懒的缘故,很少发言。但总有些话如鲠在喉,不吐不快。现在的社会比较浮躁,软件测试界 也普遍存在者这样的情绪,一些机构也利用这种情绪推波助澜。大家更多的是关注测试工具,测试技巧,而少有人去从根本上来分析、测试软件。一个优秀的软件性 能测试工程师要具有宏观和微观的软件测试观。他要分析软件的架构,了解软件的运行模式,了解通讯协议,更是一个软件开发高手。就象一个医生,他要通过多年 的深造和摸索,要了解病理、药理,他才能对症下药,好了,不多说了,说一下软件设计对软件性能的影响。这是我遇到的一些实际的例子。

    例子一:一个网站,允许注册用户可以上传一些图片、文档、影音文件,把这些文件做为大二进制文件存储到数据库中。功能并不是太复杂,软件的功能测试 没有问题,开始进行性能测试。5个用户的并发都没有通过,功能出错了,性能测试也就进行不下去了,分析原因,原来软件设计的时候,为每一个上传的文件设计 了一个“ID”字段做为主键,该字段是自增的,在ORACLE数据库中没有自增字段,需要编写触发器来自增,但是软件开发人员在应用程序中编写了一个函 数,在上传文件前从数据库中获得最大ID,然后加一,再填写其他信息,选择文件,上传,这样在多用户使用的时候必然造成ID字段值重复,系统必然出错。这 个错误修改后,进行性能测试,设计者把所有的上传文件都保存到一个数据表中,他没有考虑网站的流量和上传文件数量很多的情况,结果在进行数据库压力测试的 时候,当数据库中有10万条记录时,假设每个上传文件的大小是1M,该数据表的查询、备份、恢复都非常困难,当多用户浏览、上传这些文件时,性能严重下 降。这就是一个软件设计存缺陷。

    例子二:一个图形管理软件,架构采用的是B/S模式,通过在IE中嵌入ACTIVX控件,根据从数据库中读取出的测量点数据,在ACTIVX中绘制 成各种曲线,该测量点数据是井的数据,每米取10个点,每点有16条数据,每口井的井深平均按5000米算,500口井的数据就非常庞大了。在性能测试的 时候,我首先分析了软件的运行机制,客户端发出请求--WEB服务器(分析)--读取数据库数据--生成HTML和数据流返回客户端--客户端控件根据点 数据绘制成曲线。从这些过程中看性能的瓶颈应该在WEB服务器和数据库间。(ACTIVX控件有的性能测试工具不支持,但协议可以看成是HTTP,并可以 看成是一次请求),因ACTIVX运行在客户端,这部分的性能主要是受客户端影响。在性能测试过程中发现,性能真的是受数据读取速度的影响,更可怕的是, 该数据库竟然没有设置索引,设置索引后,软件开发人员竟然在索引字段用了trim()函数来去掉空格,造成索引字段没有起到作用,汗一个!!!!。

    从上面的例子可以看出,设计才是决定性能的关键。

     


  • informix11.5SQL跟踪与监控

    2009-09-22 23:09:22

    在 SQL 语句性能监控时,我们经常要了解 SQL 语句执行了多长时间; SQL 语句运行时占用了多少系统资源,如 CPU 占用情况、内存占用情况、磁盘 I/O 读写情况; SQL 语句等待系统资源如磁盘 I/O 及锁的时间及次数等。通过 SQL 语句对系统的资源使用及等待情况,我们可以了解到 SQL 语句运行的瓶颈,并及时调整系统资源配置,或者调整用户的应用程序。我们上面介绍的 set explain 方法,可以帮助我们了解一些 SQL 语句性能问题,但是当我们启用 SET EXPLAIN 功能时,SQL 语句性能可能已经出现了问题,为了能够让 DBA 更及时、更详细地了解 SQL 语句的资源使用情况并做出相应的调整,在 Informix 中,提供了 SQL 下钻查询特性来满足上述功能。

    SQL 下钻查询特性可以收集关于系统上执行的每个 SQL 语句的统计信息,并分析语句历史。它可以帮助您回答如下问题:

    SQL 语句需要多长时间
    各个语句使用多少资源?
    等待每个资源需要多长时间?
    查询计划是什么?
    统计信息存储在循环缓冲区(内存中名为 syssqltrace 的伪表)中,即存储在 sysmaster 数据库中。您可以动态地调整循环缓冲区的大小。

    缺省情况下,该功能处于关闭状态,但是您可以对所有用户或一组特定用户将其打开。在启用带有缺省配置的该功能时,数据库服务器跟踪运行的上 1000 条 SQL 语句以及这些语句的概要统计信息,每个 SQL 语句占用 1K 大小的空间。

    如果您想要保存大量历史信息,那么该功能需要的内存较大。 SQL 历史跟踪所需的缺省空间量为 1 兆字节。您可以根据需求增加或减少存储量。如果不想要对此使用内存,那么可以禁用 SQL 历史跟踪。

      使用 SQLTRACE 配置参数指定启动 SQL 跟踪信息

    我们可以通过修改 $InformixDIR/etc/$ONCONFIG 文件中的 SQLTRACE 配置参数来控制数据库服务器启动时的缺省跟踪行为。 所设置的信息包括要跟踪的 SQL 语句数目和跟踪方式。

    SQLTRACE 配置参数语法:

    SQLTRACE [Level=off|low|med|high],
     [Ntraces=number of traces],
     [Size=size of each trace buffer],[Mode=global|user]


    其中:

    level字段,可以指定以下某个值:

    Low:它用于捕获语句统计信息、语句文本和语句迭代器。当启用 SQL 跟踪时,它是缺省的跟踪级别。
    Medium:此跟踪级别捕获低级跟踪中包含的所有信息,再加上表名、数据库名称和存储过程堆栈。
    High:此跟踪级别捕获中级跟踪中包含的所有信息,再加上主变量。
    Off:这不指定 SQL 跟踪。系统缺省为 OFF
    ntraces字段,指定要跟踪的 SQL 语句的数目,其范围是 : 500 -2147483647 。

    size字段, 指定跟踪缓冲区大小的千字节数。每个 SQL 语句的跟踪信息使用一个跟踪缓冲区,如果超过了此缓冲区大小,那么数据库服务器丢弃已保存的数据。其范围是 : 1K-100K 。

    mode字段, 指定以下任意一项:

    Global:跟踪系统上的所有用户,它是缺省值。
    User:跟踪指定用户(如果想要获取一小组用户正在运行的 SQL 样本,那么指定此项)。
    在设置 SQLTRACE 参数时,我们需要考虑以下一些内容:

    关于 SQLTRACE 缓冲区的问题:
    我们收集到的统计信息都保存在内存的缓冲区中,它的大小 =Ntraces*Size,如果收集的语句数量越多、收集信息越详细,需要的缓冲区就越大,占用的内存资源也就越多。因此,在配置时,要考虑自己的实际情况来选择。另外,这个缓冲区是一个循环缓冲区,当缓冲区大小不够时,它会将旧的信息丢掉,因此,如果需要保存 SQL 语句跟踪历史,要考虑它的大小问题。当我们将 SQL 跟踪特性关闭时,保存在 SQLTRACE 缓冲区中的信息也会丢掉,如果需要保存,在关闭 SQL 跟踪特性关闭前,请将这些信息保存到表或文件中,防止丢失。

    关于 size 参数
    size 参数的大小主要由 SQL 语句的大小及 Level 来决定。不同的 level,所收集的信息量不同,Medium 会比 low 收集的信息量大,同样,High 会比 Medium 收集的信息量大。因此,在选择时,要充分考虑好我们收集统计信息的用途。通常,Low Level 比较适合于错误诊断及性能调优,High Level 常用来做系统负载重现功能。 Medium Level 也主要用于一些错误诊断场合。

    关于 Mode 参数
    global 模式用于跟踪系统上所有用户的统计信息,因此,当在一个比较繁忙的系统上,可能很快就会收集到大量的信息,同时,所有用户的信息都包含在一起,分析时也比较繁琐,通常,选择 global 模式,主要用于比较系统上所有会话的资源使用情况,或者是我们不清楚要分析哪一个具体用户的资源使用情况。一般情况下,我们会使用 user 模式,这样,我们分析起来会比较清晰,同时,占用的系统资源也不会太多。

    以下语句指定了数据库服务器将收集关于系统上所有用户执行的最多 2000 条 SQL 语句的低级别信息,并将分配大约 4 兆字节的内存(2000 * 2 千字节)。

    SQLTRACE level=LOW,ntraces=2000,size=2,mode=global


    以下语句指定了数据库服务器将收集关于系统上所有用户执行的最多 2000 条 SQL 语句的高级别信息,并将分配大约 4 兆字节的内存(2000 * 2 千字节)。

    SQLTRACE level=high,ntraces=2000,size=2,mode=global


    使用 SQLTRACE 配置参数方式比较适合于设置一些缺省的配置,如果需要经常变化,使用 ADMIN API 命令方式则比较方便。

    使用 ADMIN API 命令指定启动 SQL 跟踪信息

    如果不想设置 SQLTRACE 配置参数以重新启动服务器,那么可执行以下 ADMIN API 命令,该命令可提供与设置 SQLTRACE 相同的功能。使用 ADMIN API 的 task() and admin() 函数可以动态改变 SQLTRACE 的设置,不需要重新启动服务器,使用更加灵活。只有 Informix 用户有权力执行 ADMIN API 命令。通过 ADMIN API 命令修改的 SQLTRACE 的设置不会保存到 SQLTRACE 配置参数中,因此,当服务器重新启动后,SQLTRACE 配置参数值将会生效。

    当 SQLTRACE 配置参数为 OFF,我们通过下面的 ADMIN API 命令启动 SQL 跟踪信息时,系统会使用缺省的设置值。 即:

    SQLTRACE level=low,ntraces=1000,size=1,mode=global

    execute function task("set sql tracing on");


    我们也可以指定自己设置的值。以下语句指定了数据库服务器将收集关于系统上所有用户执行的最多 2000 条 SQL 语句的低级别信息,并将分配大约 4 兆字节的内存(2000 * 2 千字节)。

    execute function task("set sql tracing on", 2000,"2k","low","global");


    停止收集 SQL 语句信息,我们可以执行:

    execute function task("SET SQL TRACING OFF");


    当执行上述命令后,会关闭 SQL 跟踪功能,同时,跟踪缓冲区中的内容会丢失。

    启用特定用户的 SQL 历史跟踪

    启用特定用户的 SQL 历史跟踪,不仅可以节省系统内存资源,而且分析起来也更加清晰,一般我们会建议采用这种方式。在以用户方式启用 SQL 跟踪系统后,就可以启用对特定用户的跟踪。在指定 user 作为 SQLTRACE 配置参数中的方式后,必须执行管理 API task() 或 admin() 函数来打开对特定用户的 SQL 历史跟踪。

    如果全局 SQL 跟踪被禁用,那么可执行管理 API task() 或 admin() 函数来启用对特定用户的 SQL 跟踪。

    要启用特定用户的 SQL 历史跟踪,您可以执行 task 或 admin() 函数,并指定 set sql tracing on 和定义用户的信息。

    如果需要对 session 30 启用 SQL 语句跟踪,我们可以执行:

    execute function task("set sql tracing on", 1000, 1,"low","user");
     execute function task("set sql user tracing on",30)


    如果需要对当前连接到系统的用户(只要它们未作为用户 root 或 Informix 登录)启用 SQL 语句跟踪,我们可以执行:

    dbaccess sysadmin -<<END
     execute function task("set sql tracing on", 1000, 1,"low","user");
     select task("set sql user tracing on", sid)
     FROM sysmaster:syssessions WHERE username not in ("root","Informix");
     END


    如果需要停止对 session 30 进行跟踪,我们可以执行:

    execute function task( “ set sql user tracing off",30);


    SQL 跟踪信息显示及分析

    我们可以通过执行 onstat -g his 命令或查询sysmaster数据库中的 syssqltrace 伪表来获取 SQL 下钻查询信息。

    onstat – g his 命令

    我们可以通过执行 onstat -g his 命令来显示 SQL 下钻查询信息。

    语法:

    >>-onstat-- -g--his--------------------------------------------><


    onstat -g his 选项显示 SQLTRACE 收集到的信息并以格式化输出。缺省情况下,只有 DBSA 可以查看 onstat -g his syssqltrace 信息。然而,当 UNSECURE_ONSTAT = 1 时,所有的用户可以查看此信息。 onstat -g his 选项会将所收集到的所有信息全部显示出来,目前还不能够只显示某一特定的用户会话或 SQL 语句的信息。因此,它比较适合小数据量的显示,它的好处是比较方便。

    onstat -g his 选项的输出主要包含三部分内容:trace profile, statement text and statement statistics.

    Trace profile:这是 onstat -g his 命令输出的前几行信息,用于描述跟踪的级别、跟踪模式、跟踪的 SQL 语句条数、跟踪缓冲区的大小及跟踪缓冲区保持的时间。如下所示:

    onstat -g his 的输出示例(Trace profile 部分):

    Statement history:

     Trace Level                  High
     Trace Mode                   User
     Number of traces            50000
     Current Stmt ID                 3
     Trace Buffer size           12264
     Duration of buffer             37 Seconds
     Trace Flags            0x00007F21
     Control Block          0x4b8cd018

     ... ...



    Statement text and iterators:onstat – g his 命令输出的接下几行用来描述被跟踪的 SQL 语句以及查询中用到的迭代器及查询计划信息。 SQL 语句部分的内容根据跟踪级别的不同而有所不同。如果跟踪级别是 LOW,只是显示被跟踪的 SQL 语句及正在使用的数据库的十六进制描述。如果踪级别是 medium,将显示数据库的名称,SQL 语句,SQL 语句中用到的表名称及存储过程的调用堆栈信息。如果跟踪级别是 high,除了显示 medium level 的信息外,还将显示 SQL 语句中用到的宿主变量信息。如下所示:

    onstat -g his 的输出示例(Statement text and iterators: 部分):

    ... ...
     Statement # 3:     @ 0x4b907018
     Database:        sysmaster
     Statement text:
      select first 2 substr(tabname,1,20) as table, isreads as reads from
        sysptprof where isreads > 10 order by isreads desc

      SELECT using tables [ systabnames sysptntab ]

     Iterator/Explain
     ================
        ID   Left  Right   Est Cost   Est Rows   Num Rows    Partnum Type
         3      0      0          9         33         40         20 Seq Scan
         4      0      0          1        100          1         15 Index Scan
         2      3      4         28         33         40          0 Nested Join
         1      2      0          1         33          2          0 Sort
         4      0      0         18         92         92     Disk Scan
         2      3      4        287       1380       5060     Nested Join
         1      2      0          1          1       5060     Insert

     ... ...



    Statement information and statistics:接下来的部分主要包含 SQL 语句及性能统计信息,也是我们进行监控的最主要的部分。通过它,我们可以发现 SQL 语句相关的内存使用情况、磁盘 I/O 情况、锁使用及争用情况,CPU 使用情况,排序及索引使用情况等信息。据此,我们可以进行相应的调整。 我们又可以将其细化为下面三部分内容:

    Statement information:描述下边一些信息:

    运行命令的用户的用户标识
    数据库会话标识
    数据库的名称
    SQL 语句的类型
    SQL 语句执行的持续时间
    该语句完成的时间
    带有语句类型的 SQL 语句文本或函数调用列表(也称为堆栈跟踪),例如: procedure1() calls procedure2() calls procedure3()
    RSAM statistics:描述下边一些信息:

    缓冲区读取和写入的数目
    页面读取和写入的数目
    排序和磁盘排序的数目
    锁请求和等待的数目
    逻辑日志记录的数目
    SQL statistics:描述下边一些信息:

    估计的行数
    优化器估计成本
    返回的行数
    SQL/ISAM 错误
    数据库隔离级别
    SQL 语句内存使用量。
    onstat -g his 的输出示例(Statement information and statistics 部分):

    ... ...

     Statement information:
      Sess_id  User_id  Stmt Type          Finish Time    Run Time
      26       501      SELECT             23:31:01       0.0054

     Statement Statistics:
      Page       Buffer     Read       Buffer     Page       Buffer     Write
      Read       Read       % Cache    IDX Read   Write      Write      % Cache
      0          410        100.00     0          0          0          0.00

      Lock       Lock       LK Wait    Log        Num        Disk       Memory
      Requests   Waits      Time (S)   Space      Sorts      Sorts      Sorts
      0          0          0.0000     0.000 B    1          0          1

      Total      Total      Avg        Max        Avg        I/O Wait   Avg Rows
      Executions Time (S)   Time (S)   Time (S)   IO Wait    Time (S)   Per Sec
      1          0.0108     0.0108     0.0054     0.000000   0.000000   370.1291

      Estimated  Estimated  Actual     SQL        ISAM       Isolation  SQL
      Cost       Rows       Rows       Error      Error      Level      Memory
      28         33         2          0          0          CR         34176



    输出描述 :

    Page Read:已从磁盘读取的页数
    Buffer Reads: 从缓冲池读取而不是从磁盘读取页面的次数
    Read % Cache: 应从缓冲池读取页面的次数的百分比
    Buffer IDX Read: 索引页的缓冲区读取数
    Page Write: 写入磁盘的页数
    Buffer Write:修改并发送回缓冲池的页数
    Write % Cache:页面写入缓冲池而不是写入磁盘的次数的百分比
    Lock Requests:该语句所需的锁的总数
    Lock Waits:该 SQL 语句等待锁的次数
    LK Wait Time:在该 SQL 语句执行期间,用于等待锁的时间(以秒为单位)
    Log Space:
    Num Sorts:用于执行语句的排序总数
    Disk Sorts:对于该 SQL 语句,对磁盘执行的排序的次数
    Memory Sorts
    Total Executions:该语句已执行的总次数,或者该游标重用的次数
    Total Time:执行该语句的总时间(以秒为单位)
    Avg Time:执行该语句的平均时间(以秒为单位)
    Max Time:运行 SQL 语句的总时间(以秒为单位),不包括应用程序使用的任何时间
    LK Wait Time:语句等待应用程序锁的时间量
    Avg IO Wait:语句等待 I/O 的时间量,不包括任何异步 I/O 。
    Avg Rows Per Sec:该语句每秒产生的平均行数
    Estimated Cost:与 SQL 语句关联的代价
    Estimated Rows:返回的估计行数,由语句的优化程序估计
    Actual Rows:对于该语句返回的行数
    SQL Error:SQL 错误号
    ISAM Error:RSAM/ISAM 错误号
    Isolation Level:该语句运行时使用的隔离级别
    SQL Memory:该 SQL 语句需要的字节数
    syssqltrace 伪表

    在 Informix 中,提供了 3 张内存伪表用来保存 SQL 跟踪信息。其中,syssqltrace 表用来提供被跟踪的每一个 SQL 语句的详细的跟踪信息。它的大小由 ntraces*size 来决定。我们可以动态调整其大小。我们可以通过 sysmaster 数据库来访问这 3 张内存伪表。

    syssqltrace 表的输出信息同执行 onstat -g his 命令输出的 Statement information and statistics 部分的内容相似。

    由于我们可以使用 SQL 语句访问 SQL 跟踪信息,所以,采用该种方法比较适合查询有关单个 SQL 语句或一组 SQL 语句的详细跟踪信息。

    syssqltrace 表的基本结构如下:

    列 类型 描述
    sql_id int8 唯一 SQL 执行标识
    sql_address int8 代码块中的语句的地址
    sql_sid int 运行 SQL 语句的用户的数据库会话标识
    sql_uid int 运行 SQL 的语句的用户标识
    sql_stmttype int 语句类型
    sql_stmtname char(40) 显示为单词的语句类型
    sql_finishtime int 此语句的完成时间(UNIX)
    sql_begintxtime int 此事务的启动时间
    sql_runtime float 语句执行时间
    sql_pgreads int 此 SQL 语句的磁盘读取数
    sql_bfreads int 此 SQL 语句的缓冲区读取数
    sql_rdcache float 从缓冲池读取页的时间百分比
    sql_bfidxreads int 索引页缓冲区读取数
    sql_pgwrites int 写入磁盘的页数
    sql_bfwrites int 已修改并返回到缓冲池的页数
    sql_wrcache float 页已写入缓冲池,但未写入磁盘的时间百分比
    sql_lockreq int 此 SQL 语句所需锁总数
    sql_lockwaits int SQL 语句等待锁的次数
    sql_lockwttime float SQL 语句期间系统等待锁定的时间
    sql_logspace int 逻辑日志中 SQL 语句所用空间量
    sql_sorttotal int 为语句运行的排序数
    sql_sortdisk int 磁盘上运行的排序数
    sql_sortmem int 内存中运行的排序数
    sql_executions int SQL 语句运行的次数
    sql_totaltime float 运行语句所用时间总量
    sql_avgtime float 运行语句所用平均时间量
    sql_maxtime float 执行 SQL 语句所用最大时间量
    sql_numiowaits int I/O 操作必须等待的次数
    sql_avgiowaits float SQL 语句必须等待的平均时间量
    sql_totaliowaits float SQL 语句必须等待 I/O 的时间总量。这不包含任何异步 I/O 。
    sql_rowspersec float 产生的平均行数(每秒)
    sql_estcost int 与 SQL 语句关联的成本
    sql_estrows int 按照优化器的预测为 SQL 语句返回的预估行数
    sql_actualrows int 为 SQL 语句返回的行数
    sql_sqlerror int SQL 错误号
    sql_isamerror int RSAM/ISAM 错误号
    sql_isollevel int SQL 语句的隔离级别。
    sql_sqlmemory int 执行 SQL 语句所需字节数
    sql_numiterators int 语句所用迭代器数
    sql_database char(128) 数据库名
    sql_numtables int 执行 SQL 语句中所用表数
    sql_tablelist char(4096) SQL 语句中直接引用的表名列表。如果 SQL 语句击发对其他表执行语句的触发器,将不列出其他这些表。
    sql_statement char(1600) 已运行的 SQL 语句


    如果我们要查看会话 30 的 SQL 跟踪信息,可以执行:

    select * from syssqltrace where sql_id =30;


    syssqltrace_info 伪表

    syssqltrace_info 伪表也是一张内存表,用来保存 tracing profile 信息。我们可以通过 sysmaster 数据库来访问这张内存伪表。 tracing profile 信息主要用于描述跟踪的级别、跟踪模式、跟踪的 SQL 语句条数、跟踪缓冲区的大小及跟踪缓冲区保持的时间。

    syssqltrace_info 伪表的输出内容同执行 onstat -g his 命令输出的 tracing profile 部分的内容相似。

    syssqltrace_info 表的基本结构如下:

    列 类型 描述
    flags integer SQL 跟踪标志
    ntraces integer 要跟踪的项数
    tracesize integer 为各 SQL 跟踪项存储的文本的大小
    duration integer 跟踪缓冲区(以秒为单位)
    sqlseen int8 启动或调整大小以来跟踪的 SQL 项数
    starttime integer 跟踪的启用时间
    memoryused int8 SQL 跟踪所用内存的字节数


    syssqltrace_iter 伪表

    syssqltrace_iter 伪表也是一张内存表,用来保存 Statement text and iterators 信息。我们可以通过 sysmaster 数据库来访问这张内存伪表。 Statement text and iterators 信息主要用来描述被跟踪的 SQL 语句以及查询中用到的迭代器及查询计划信息。这个表常用来查询特定 SQL 语句的查询计划信息。

    syssqltrace_iter 伪表的输出内容同执行 onstat -g his 命令输出的 Statement text and iterators 部分的内容相似。

    syssqltrace_iter 表的基本结构如下:

    列 类型 描述
    sql_id int8 SQL 执行标识
    sql_address int8 SQL 语句块的地址
    sql_itr_address int8 迭代器的地址
    sql_itr_id int 迭代器标识
    sql_itr_left int 向左的迭代器标识
    sql_itr_right int 向右的迭代器标识
    sql_itr_cost int 迭代器成本
    sql_itr_estrows int 迭代器预估行数
    sql_itr_numrows int 迭代器实际处理的行数
    sql_itr_type int 迭代器类型
    sql_itr_misc int 迭代器杂项标志
    sql_it_info char(256) 显示为文本的迭代器杂项标志


    如果我们要查看 sql_id=15 的查询所使用的迭代器及类型,我们可以执行:

    select  sql_itr_type,
            substr(sql_itr_info,1,20) as iterator_info,
            sql_itr_numrows
     from    syssqltrace_iter
     where   sql_id = 14;



    通过执行 onstat -g his 命令或查询sysmaster数据库中的 syssqltrace 伪表,我们可以查看系统中运行的 SQL 语句、执行 SQL 所用的资源、运行 SQL 花费的时间、磁盘 / 页面 / 缓冲区读和写的数量、使用的锁数量、排序数量和使用的内存量。另外,还可以查看 Informix 优化器估计的运行 SQL 所要花费的时间。这样,我们可以了解到 SQL 语句占用资源情况及存在的资源瓶颈,并进行相应的调整。另外,我们还可以对比 Informix 优化器估计的返回行数和实际的返回行数(sql_estrows 和 sql_actualrows)。如果这两个数值差异很大,就说明 Informix 优化器并不掌握关于表中行和索引数量的正确的统计数据。这意味着需要运行 update statistics,从而向优化器提供正确的数据。

    另外,通过查询 syssqltrace 表,我们还可以发现系统中运行时间最长的 SQL 查询、带有太多表连接操作的查询、不希望的连接类型、返回记录太多的查询、存在锁等待的查询等信息,以便于我们进行及时的调整及改进来提高 SQL 语句的性能。

    如果我们要发现运行时间最长的 SQL 查询,我们可以执行:

    select  first 5
            substr(sql_statement,1,50) as statement
            , sql_avgtime as Average_Time
            , sql_executions as Number_of_times
     from syssqltrace
     order by sql_avgtime desc ;



    如果我们要发现返回记录太多的查询,我们可以执行:

    select  first 5
            sql_estrows as est_rows
            , sql_actualrows as actual_rows
            , substr(sql_statement,1,30) as statement
     from syssqltrace
     order by sql_actualrows desc ;

  • 性能测试项目反思

    2009-06-09 10:39:58

    现在一说性能测试、性能调优,好多人首先想到的是用LOADRUNNER等测试工具,好像没有这些工具就不能进行性能测试就不能进行性能调优。真是这样的吗?其实工具
    固然重要,但更重要的是系统的分析、测试案例的设计。正好刚刚结束了一个软件性能测试的项目,有些感触,整理一下,也为了给大家一个参考。
          前段时间一直在搞自动化测试框架SAFS、STAF等方面的东西,那个确实比较难搞。领导突然安排去做一个性能测试项目,已经近4个月没有搞性能测试了,心里
    确实有点没有底。配置的人员也比较少,并且经验也不足。我们首先分析了系统架构、业务特点、运维数据。发现系统的性能和用户数的多少并没有太多的关系,
    初步确定是因为某些模块的程序编写有性能缺陷。在运行程序时,明显发现有些功能响应缓慢。因为时间比较紧,并且测试环境并不是独立供性能测试使用,功能
    测试也在同一环境下进行,并且还没有给我们开通数据库DBA权限和服务器操作系统的超级用户权限,限制非常多,所以我决定分两步进行,让其他同事编写性能测试
    测试案例和脚本,我来分析系统响应时间缓慢的原因,初步判断应该是数据库方面的原因。因为给我开通的数据库用户只有查询权限,所以我只能用SQL语句来查询
    追踪后台运行的SQL,通过select sql_text,sql_id,users_executing,executions, loads from v$sqlarea;来查询后台正在执行的SQL,通过得到的SQL_ID查询SQL语句
    select * from v$sqltext where sql_id ='75yzszjxyrrva',然后根据HASH_VALUE得到完整的SQL,select * from v$sql where hash_value='2079055722'.捕获SQL后发现
    两条SQL语句运行较慢:1、select b.case_id,report_no,report_time,b.organ_id,realname,accident_time, reporter_name,accident_type,certi_type,register_id, recorder_id,  certi_code,  accident_status, has_image, accident_type, diff_date,   to_char(max(ti2.scan_time), 'YYYY-MM-DD HH24:MI:ss') as scan_time from (  select distinct tcc.case_id,tcc.case_no as report_no,tcc.report_time,tcu.real_name as realname,tcc.accident_type, tcc.accident_time,tcc.register_id,tcc.reporter_name,trc.certi_type,trc.certi_code,tcc.accident_status,tcc.recorder_id,tcc.organ_id,tcc.case_type,  sysdate - trc.insert_time as diff_date,decode(ti.case_id, null, -1, 1) as has_image  from t_report_case trc ,t_claim_case tcc,t_customer tcu,t_image ti ,t_employee te where trc.case_id = tcc.case_id  and tcc.case_id = ti.case_id(+)  and tcc.register_id = te.emp_id  and tcc.register_id = 3381221 and tcc.insured_id = tcu.customer_id(+)  and tcc.case_status=4  and tcc.case_type = te.case_type   )b  , t_image ti2 where ti2.case_id(+)=b.case_id     group by b.case_id,report_no,  report_time,      b.organ_id,       realname,       accident_time,       reporter_name,       accident_type,       certi_type,       register_id,       recorder_id,       certi_code,       accident_status,       has_image,     accident_type,       diff_date order by has_image desc,report_time asc

    执行用时6.672秒。2、(   select tpp.prem_id,tpp.policy_id,tpp.fee_type,tpp.pay_mode,           tpp.fee_status,tpp.actual_prem,tpp.due_time,tgp.holder_id as customer_id,           tgp.send_code,tgp.policy_code as policy_code, tpp.policy_type,          tpp.insured_id,tif.insured_num,' ' as notice_code      from t_policy_prem tpp,t_group_policy tgp,t_insured_first tif    where  ((tpp.fee_status=0 and tpp.pay_mode in(1,2))or(tpp.fee_status in(0,3,4) and tpp.pay_mode=3))      and tpp.fee_type= :1      and tpp.insured_id=tif.insured_id(+)      and tpp.policy_id=tif.policy_id(+)      and tpp.policy_type = '2'      and tpp.policy_id = tgp.policy_id      and tgp.send_code = :2  )  union  (   select tpp.prem_id,tpp.policy_id,tpp.fee_type,tpp.pay_mode,           tpp.fee_status,tpp.actual_prem,tpp.due_time,tp.holder_id as customer_id,           tp.send_code,tp.policy_code,tpp.policy_type,           tpp.insured_id,tp.insurant_num as insured_num,' ' as notice_code      from t_policy_prem tpp,t_policy tp    where 1=1      and  ((tpp.fee_status=0 and tpp.pay_mode in(1,2))or(tpp.fee_status in(0,3,4) and tpp.pay_mode=3))      and tpp.insured_id is null      and tpp.policy_type in ('1','3')      and tpp.fee_type= :3      and tp.send_code = :4       and tpp.policy_id = tp.policy_id     )    order by due_time,fee_type
    执行用时4.8秒左右。分析这两条SQL语句的执行计划,SQL1的COST值是一个天文数字,SQL2的COST的值是1700多,不算太高。明显第一条SQL语句需要优化,分析SQL1后
    建议优化为:select b.case_id,report_no,report_time,b.organ_id,realname,accident_time, reporter_name,accident_type,certi_type,register_id, recorder_id,  certi_code,  accident_status, has_image, accident_type, diff_date,   to_char(max(scan_time), 'YYYY-MM-DD HH24:MI:ss') as scan_time from (  select distinct tcc.case_id,tcc.case_no as report_no,tcc.report_time,tcu.real_name as realname,tcc.accident_type, tcc.accident_time,tcc.register_id,tcc.reporter_name,trc.certi_type,trc.certi_code,tcc.accident_status,tcc.recorder_id,tcc.organ_id,tcc.case_type,  sysdate - trc.insert_time as diff_date,decode(ti.case_id, null, -1, 1) as has_image,scan_time  from t_report_case trc ,t_claim_case tcc,t_customer tcu,t_image ti ,t_employee te where trc.case_id = tcc.case_id  and tcc.case_id = ti.case_id(+)  and tcc.register_id = te.emp_id  and tcc.register_id = 3381221 and tcc.insured_id = tcu.customer_id(+)  and tcc.case_status=4  and tcc.case_type = te.case_type   )b       group by b.case_id,report_no,  report_time,      b.organ_id,       realname,       accident_time,       reporter_name,       accident_type,       certi_type,       register_id,       recorder_id,       certi_code,       accident_status,       has_image,     accident_type,       diff_date order by has_image desc,report_time asc
    修改后的执行用时是0.047秒左右。
    第二条SQL比较麻烦,通过用具体数据替代绑定变量执行速度很快,而在程序中却很慢,真的不知道是什么原因,与开发人员通过写日志逐行对代码进行检查,发现
    在receivedao.java文件中checkFullARSENDCODE(String s)函数中有这这行代码,
    preparedstatement.setLong(4, Long.parseLong(s));检查数据库,SENDCODE字段是字符型,传递的参数却是LONG型,

    更改为:preparedstatement.setString(4, Long.parseLong(s));

    效率明显提高,因为在SQL语句中传入的参数类型错误,如果传入的是长型就不走索引了,是全表扫描。这样的错误还真不好发现啊!

    通过这个例子,可以发现,不用自动化工具,不用编写脚本就可以发现一些明显的性能瓶颈的。
  • 如何跟踪SQL语句

    2009-02-17 10:35:10

    做性能测试的时候,系统就是一个黑盒子,你不清楚系统是如何运行的,但数据库的结构是可以看到的,SQL的运行在ORACLE中都会留下痕迹,根据这些SQL你可以大概了解系统的运行方式,在ORACLE动态性能视图中,有V$SESSION,V$SQL这两个视图,V$SESSION记录的是会话记录,V$SQL记录的是已解析的,并保存在SGA内存中的SQL语句,通过这样一个SQL语句,你就可以了解最近的系统运行的SQL。
    select * from v$session a,v$sql b where a.USERNAME='CUPS' and a.PREV_SQL_ADDR=b.ADDRESS

    然后查询sql_text,sql_fulltext字段内容就可以了解SQL的情况。
  • oracle B树索引深入研究

    2009-02-09 10:52:35

  • 有效性能测试

    2009-02-04 09:15:06

    “为什么我上线系统的性能和性能测试的结果相差很大呢?”这是一些用户会经常碰到的问题。当然产生这个问题的原因很多,下面我用一个很典型的例子来说明一下。一个用户登录界面,要求用户输入用户名、密码点击登录,登录系统。程序的处理流程如下:
    根据输入的用户名、密码生成SQL语句,select roleID from usertable where username='用户名' and password='密码',把这条语句发给ORACLE数据库,从数据库中查询数据,如果查询的roleID不为空则是合法用户允许登录,否则不允许登录系统。这是一个非常简单的系统。性能测试人员用LOADRUNNER录制脚本,然后用逐步加压的方式来运行脚本,TPS、ORACLE的命中率、资源占用都很理想。性能测试人员就陷入了一种盲目的乐观情绪中,就认为系统性能没有问题,结果在实际运行中系统性能与性能测试中的性能相差很大,为什么会出现这种情况呢,下面我们来分析一下:
    首先我们来了解一下ORACLE的运行机制:从客户端发送一条SQL语句到ORACLE服务端,ORACLE要对SQL语句进行解析、执行、返回结果。并且ORACLE有一个LRU(最近最常使用的语句)机制,把最近最常使用的SQL语句保存到共享内存SGA中的libary cache中,下一次再有这样的请求它就不解析了,直接从共享内存中使用。假如我们使用的SQL语句是select roleID from usertable where username='AAA' and password='123',在我们加压的时候它就解析一次或很少的几次,其他的请求就会从共享内存中取得,并且返回的结果也会保存到BUFFER CACHE中,这样系统的测试结果当然就是很好的。但在实际工作中,用户名和密码是各种各样的,而ORACLE解析的条件又要求非常苛刻,SQL语句有一点不同它就认为是不同的SQL语句就要重新进行解析,而解析非常耗费系统资源,所以在实际运行中系统的性能和性能测试的结果相差很大。通过这个例子我们可以看出我们没有把真正的压力压到点上,也就是进行的不是有效性能测试。


    如何进行有效性能测试呢?一定要仔细地分析你要进行测试系统的架构、技术体系,LOADRUNNER只是一个加压工具,它对ORACLE的监控也非常的不好,不要盲目的相信LOADRUNNER。一定要充分重视测试的调研和设计工作,如果能在测试前拿到系统开发的各种文档是最好的,如果没有也要充分调研业务人员、开发人员、系统运维人员,了解系统的技术架构、业务组成、业务流程、业务频度、数据量等要素,这样才能进行有效性能测试。性能测试是非常有挑战性的工作,不是简单的几天就能搞好的,要多积累,多学习,没有捷径可言,特别是刚做性能测试或做了一段时间的性能测试人员一定要充分注意。
  • 2009春晚的一点感想

    2009-02-04 09:14:04

    在2009年春节联欢晚会上有一个小品是讲潜艇兵的生活的,其中有一句话让我感触很深,“我们潜艇兵拜年不说‘新年好!’,我们也是三个字‘请放心!’”。这三个字把责任、使命、情感全部凝聚在了一起,他们守护的是祖国的安全,而我们软件测试人员是软件质量的把关人员,也是软件发布的最后一个环节。对用户、对开发人员、对公司领导你能否也用“请放心”来回答呢?如果你能这样回答,说明你不仅仅把软件测试做为一份工作而是做为一种使命,如果做为一种使命,你的测试人生绝对会很精彩。
    潜艇兵要深深地潜在海底,你看不到他的轨迹和航线,他们是那样的默默无闻那样的不为人知;软件测试人员的测试生活也很枯燥、繁琐,没有软件设计、软件开发人员那样的有创造激情和成就感。但请相信没有潜艇兵的海底守护,祖国的安全无法保障,没有测试人员的辛勤工作,软件的质量也无法保障。在这新春伊始的时刻,请你和我一起说一声“请放心”!

  • 领导测试团队的艺术

    2009-01-20 08:59:32


    现在软件的规模越来越大,过去那个一个人关在房子里二、三个月编写一套软件的个人英雄时代已经过去了,团队的合作越来越被大家重视,也是软件发展的必然趋势。而如何有效地管理一个团队也是仁者见仁智者见智,我把我个人的一些认识写出来,也供大家讨论一下。管理是一门艺术,而艺术是需要天赋的。

    首先我们来讨论一下做为一个团队的领导者的基本要求:
    1、态度
       我认为态度是第一位的,做为一个团队的领导者,是带领团队攀登一个又一个高峰获得一个又一个辉煌还是混日子就决定了一个团队的方向。
    2、性格
       每个人的性格因为成长的环境不同是千差万异,但做为一个团队的领导者沉着稳重是必须具有的。
    3、能力

      亲和力和凝聚力:
       这决定了你是否能真正融入你的测试团队,你只有真正融入到这个团队,而不是一个高高在上的领导者,这个团队才是一个有真正战斗力的团队,大家如果有对历史有兴趣,大家可以看看为什么中国共产党领导的军队为何能在实力相差非常悬殊的情况下能打败美式装备的国军,官兵一体,干部冲锋在前是非常重要的一项。得民心者得。。。。。
       组织协调能力:
    一般一个测试团队的领导要向公司的高层管理者负责,要管理测试团队,还要与用户交流(外包类),因此如何灵活地协调各方的关系就考研测试团队领导者的水平了。测试团队是一个技术团队,团队内部的技术交流、项目信息的交流沟通也是非常重要的。
     
       技术能力:
       在中国这种环境下,做为一个技术团队的领导者我绝对不赞同用外行,那样不仅用户不放心,团队成员也不会尊重他(她),但也不是说明非得该领域内的专家来做为管理者,做为一个技术团队的管理者你最少要对该技术领域很熟悉,并且要有很强的学习能力,现在软件技术的发展日新月异,测试技术要求知识面要宽,但深度就要求的相对开发要低。

    其次我们来讨论一下测试团队的组成:
        战争是集体作战,不是个人间的单打独斗,而团队作战,阵法和阵型在战术层面就是第一位的(战略最重要,本文中不涉及)如篮球、足球,包括现代的特种战争也非常重视战斗队形。在这里我说一下我非常尊重的抗倭名将戚继光的鸳鸯阵,该阵队形是2-3-2或2-2-1或2-1队形,可以随着地形或战争的变化而变化,最基本的配置是这样,2名藤牌手在队伍的最前面,配腰刀,主要是防守整改队伍,3名长枪手,在中距离上进攻,保护藤牌手和后面的毛筅手(长竹子),毛筅手利用很长的竹子在远距离上攻击敌人,这样长、中、短距离都能攻击,并且互相配合、互相保护。毛筅手是该小组的领导者。
        在一个测试团队中最少要有这样四种岗位:测试领导者、测试设计者、测试执行者、测试分析者,随着项目的不同还可以邀请开发人员、数据库人员、网络管理员、系统管理员参加。
        测试团队组建完成,也要根据每个人的知识、性格、爱好进行分工,我认为要全面培训、重点侧重。争取在每个领域都要有一个领域专家,如一个团队中有一到两个DBA,所有关于数据库测试的设计、监控、分析都可以有这一二个人完成。当然团队内部关于测试工具、测试方法的培训也要让他们参加,让他们也了解。这样的团队是一个分工合作的团队才是一个可功可守的团队。

    好了,写了这些,一家之言。
      

  • 软件性能问题的几点分析

    2009-01-15 14:43:32

    2008年已经过去了,忙忙碌碌的一年,依旧有点迷茫的一年,静下心来,泡壶茶,点支烟,整理一下自己的心情和思路,也整理一下这些年在性能测试中发现的问题,总结了一些

    原因,也算是自己的一个笔记,也为自己的测试路留下一些痕迹。

    第一、结构设计不合理造成的性能问题
          我发现这类问题是造成性能问题最多的,也是性能调优的重点,通过对结构的调整,性能变化也最明显。结构设计包括程序结构设计和数据结构设计,这两部分一定要综合

    考虑,但我发现大多数的软件对程序结构设计偏重的多,对数据结构设计考虑的不是太充分,在下面的例子中我会说明。
          例子一:GIS在线编辑图形
          在ARCGIS SERVER 9中提供了通过WEB程序来编辑图形的功能,但它的工作机制是,只要客户端启动了编辑功能,后台ARCGIS SERVER就要启动一个进程(类似与启动了一个

    ARCMAP),所以对后台的性能压力是非常大的,特别是CPU。如果程序在结构设计的时候没有考虑这些问题,当较多的用户进行图形编辑的时候,系统就会崩溃。事实也确实是这样

    ,当进行性能压力测试的时候,在5个用户压力下,WEB服务器、数据库服务器的压力都非常小,而ARCGIS SERVER已经几乎不能运行了。这部分的设计应该借鉴中间件的思路,简历

    一个一直运行的进程,设立一个最大数,当用户有图形编辑的要求时,就把请求发到进程池中,如果有空闲的进程就直接利用空闲的进程,否则就等待。
          例子二:大文件的上传
          在一个《企业信息门户》中,允许用户上传一些资料,在数据库设计中,这些资料是保存在一个表中的BLOB字段中,并且有一个编号ID做主键,这样在用户量比较小的时候

    是没有问题的,当用户数比较大时,并且并发比较大时,对ORACLE的内存占用很大,并且因为有索引,插入时还要更新索引,开销更大,如果把文件保存到硬盘上而不是保存到数

    据库中,随说磁盘的IO速度较慢,但因为是网络的文件传输,网速有限制,这样比存到数据库中的性能要提高很大。
          例子三:大数据表问题
          在一个关于“测井曲线”成图的系统中,因为是把各个点生成曲线,数据量非常大,这样造成一个表非常大,在进行数据结构设计时,对该表的容量没有充分考虑,造成程

    序运行一段时间后非常慢,把大数据表进行分区后,效果非常明显。

    第二、程序编写过程中非优化语句
          编写高性能代码有很多要注意的东西,因为我关注的是数据库方面的,所以会从SQL语句方面的优化来说一下,程序员在编写代码的时候因为水平不同,并且没有考虑数据库

    中数据量的问题,编写的代码在功能测试时是没问题,但当进行稳定性测试的时候,数据库中有很多测试数据的情况下,系统的性能下降就很明显了。比如一个新闻表中,有

    ID,NEWS,DATE,CLASSE,AUTHOR这样几个字段,ID是主键,每天大概有2000条的增量,每年有72万条的增量,这样一条语句 select * from table where class ='1',可以看到就是

    建立了索引,该表还是进行全表扫描,当运行一年后,系统的速度大家就可以相象了。
          还有一些需要用存储过程的,也是在程序中编辑SQL语句,该使用绑定变量的也没有使用绑定变量,等等问题。
    题后话,写程序易,写好的程序不易。性能测试易,做好性能测试不容易。小布老师就说过,虽然现在搞性能测试的人很多,但水平高的做性能测试的,他没碰见几个,他认为先

    搞清原理,认真做好有效高效的测试设计才是做好性能测试的基础。

  • 功夫在诗外

    2009-01-04 16:58:20

    在软件行业也是摸爬滚打了好多年了,现在也是在从事测试、数据库性能调优的工作,回头看看走过的路,颇多感慨。感触最深的是“功夫在诗外”。

    我喜爱武术,小时候跟着师父练武,总是想多学套拳,以比其他师兄弟多会套拳为荣。而师父给我说了一句我受益终生的话“学拳要明理”。万道归宗,任何一门拳术练习到最高境界它的道理是相通的。如果没有扎实的基本功做基础,练拳与练功没有互相促进,你到老就是会1000套拳,你也不是高手,你的击技能力还是很差,但可惜的是,这个错误我在软件上又犯了一次。

    从事软件以来,我以会多少语言,掌握多少工具为荣,而没有认认真真地去从体系结构、通讯协议来入手。现在也看到不少同行在问一下测试工具,测试技巧颇为惋惜,大道不为而求小技,惜哉!倚天剑、屠龙刀随为利器,在高手手中一花一叶也足以制人于死地。

    个人认为做性能测试,先从体系结构入手,结合实际业务,了解各环节工作原理这样才能逐渐提高。如果只是偏好与测试工具,而原理不知就如孔乙己的回字的四种写法,徒增笑耳!知识、经验的积累是一个逐渐的过程,在目前这个日益浮躁的情况下,很多人不愿意去下功夫,如果这样你永远进入不了高手之列。

  • 性能优化从细节做起

    2008-12-25 10:07:48

    近期在测一个金融单位的业务系统,在第一轮和第二轮压力测试中发现,当并发用户在50左右时,数据库的活动会话最大也就4个,该系统的中间件是WEBLOGIC,因为该系统是自己开发的数据库连接池,所以WEBLOGIC监控不到数据库连接池的状态,所有的压力都集中在WEBLOGIC,而数据库压力很小。经过与开发人员讨论后,他们进行了程序修改,在第三轮测试的时候发现压力达到100并发用户时,数据库CPU的占用率达到97%以上,并且发现库缓存未命中率(libcache miss hit radio)在4%左右,这说明数据库的硬解析较多,通过对数据库进行分析,发现有一条SQL语句是select max(id) from table1 where ...。发现该表数据量增速较快,ID字段是自增并且是主键,把SQL语句改了一下,改为 order by ID ,取第一条记录,速度快了一倍多,CPU的使用也下来了。因为MAX函数是一个比较函数,在数据量很大时,比较非常占用CPU资源,并且使用这个函数,索引也起不到作用,而利用ORDER BY 语句,索引很快就可以定位到最大的ID,速度也非常快。细节决定成败啊,做性能测试一定要认真分析,从细节入手。

     

    注:刚学习LINUX对该系统不是太熟悉,刚学一招  实际使用内存=总内存-FREE-CACHE-BUFFER.

  • webgis性能测试实践

    2008-10-15 19:15:02

    从事webgis测试有几年的时间,说来惭愧,做webgis性能测试的时候不多,而性能测试是webgis是绕不过去的,在性能测试的时候真的有很多收获,在这里以一个实际的webgis性能测试例子说明性能测试的过程。

           这是一个西部油田WEBGIS系统,开发语言ASP.NET,GIS平台是INTERGRAPHY公司的webmap 6.0,数据库是ORACLE9.2。在这里首先重点要解释一个性能测试的术语“并发”,并发并不一定要是两个或多个同样的操作,两个或多个操作请求同时到达服务器,形成对服务器的压力,就叫并发。如在WEBGIS图形操作中,一个人执行放大操作,一个人执行缩小操作,一个人执行平移操作,只要操作请求是同时到达WEBGIS应用服务器,形成了对WEBGIS应用服务器的压力,这就形成了并发。而在WEBGIS系统中,用户对图形的操作一般思考时间是比较短的,所以WEBGIS系统的并发比例要高于一般的WEB系统的。

           其次,要做WEBGIS系统的性能测试,一定要深入了解WEBGIS系统的工作原理,了解WEBGIS系统的系统结构,一般的WEBGIS系统结构如下。

     

    WEBMAP是基于COM组件的开发方式,安装完成后要配置DCOM权限,在服务启动后,在“windows资源管理器”中的“进程”栏中,会看到GMWebMap.exe进程。

     

    WEBMAP的开发流程

     

    说明:WEBGIS应用服务器产生地图,写入到服务器中的缓存文件夹中,并根据客户端的请求,返回到客户端。

    特别说明:WEBMAP会根据你购买的license来决定你能启动几个GMWebMap.exe进程。并不是支持几个并发用户,这点要特别注意,我就曾陷入过这样的陷阱。

     

    朴素的开发过程包括六个步骤:获得地图服务对象、指定坐标系统、连接数据源、定义特征类结果集、设置显示规则、产生地图。

    MapServer对象通过两个步骤实现,首先使用IISSERVER对象创建MapServerManager对象,然后通过 MapServerManager对象的MapServer方法获得MapServer对象,代码描述如下:(ASP程序,脚本语言为VBscrīpt
    <HTML><HEAD></HEAD><BODY>
    <% Set ōbjSesMgr = Server.CreateObject("GMWebMap.MapServerManager")
    Set ōbjMS = objSesMgr.MapServer("")
    objMS.Clear %>
    </BODY></HTML>
    MapServerManager
    对象管理系统的MapServer进程,如果要成功的获得一个MapServer对象,系统当时必须有一个空闲的可用的MapServer进程,如果没有 任何可用的进程,MapServerManager对象会等待一个指定的时间段(time out)同时轮询直到得到可用的MapServer进程。
    MapServer
    对象会缓存通过服务器产生的最后一个地图的相关信息,这些信息包含连接信息、特征结果集信息等。所以有了上面例程中的objMS.Clear语句。 MapServer对象的Clear方法用来清除缓存的特征类信息,如果要清除连接信息,则需要使用DataSourceRemove方法。

     

    通过上面的流程大家可以看到,虽然所有的请求都要经过IIS服务器,但获得地图服务对象,生成图形等复杂的操作都是WEBGIS服务器完成的,系统瓶颈应该是在WEBGIS应用服务器上。而WEBGIS是基于COM方式,在并发操作时必然产生进程的争用。基于上面的分析。我用LOADRUNNER8.1录制了WEBMAP自带的示例程序,录制过程很简单,在运行压力时,我首先采用2个用户,连续运行2分钟,监测数据主要监测“系统响应时间”和“吞吐量”,然后分别用5102050个用户连续运行2分钟。结果发现每次测试结果,“响应时间”曲线都是线性增长,并且在50个用户时,系统发生错误,运用“关联分析”,发现和CPU,内存和磁盘都有很大关系,也证实了前面的分析结果。

           基于COM方式的WEBGIS系统,在并发操作时产生进程争用,虽然有轮询,但必然会影响系统响应时间,并且生成地图写入缓存文件夹时,磁盘的转速等也必然对响应时间产生影响。做测试,前期详尽的分析非常重要,庖丁解牛,之所以游刃有余,就在于对牛的结构非常清晰。

     

     

     

     抱歉,因为图形传不上来,先写这些,我会把图片传上来的。

     

     

     

     

     

  • LR录制完成后自动关闭问题的解决方法

    2008-09-19 17:14:04

       近期碰到一件比较奇怪的事情,用LR录制完成后,但见“停止录制”按钮,LR突然自动关闭了,录制后的代码也没办法保存,很是郁闷,也没找到原因,在网上搜了一下也没找到较好的办法。

       出了问题总要解决,想到前段时间还是好好的。一点点找原因,突然想到是不是因为自己把工作文件夹更改了一下,赶快试一下,更改回来,再录制,好!成功,大喜,不敢独乐乐,发出来与大家共享。

       在录制开始的时候,有如下设置界面

    画红线的部分就是“工作文件夹”,我以前做过修改,估计是有些文件没有找到,我改过来后,就好了,大家可以试一下。

     

  • 用LR录制WEB系统时协议的选择

    2008-09-19 16:50:37

        以前用LR录制WEB系统选择什么协议,我也很是迷惑了很多。鄙视一下,自己的知识还是不是很扎实,许多知识还理解的不是很透彻。汗!还做了一段时间的测试讲师。在网上也搜了很多大虾的宝贵言论,感觉还是有点云山雾罩的,自己多摸索,多实践吧,实践出真知啊。

        先说一下要测试的一个系统,是一个WEBGIS的WEB系统,地图的浏览和操作依托客户端网页内嵌的ACTIVX控件,客户端提交需求,WEBGIS服务器根据请求在服务端生成地图,然后把生成的地图反馈回客户端。我采用了两种方案。一、因为是WEB系统,根据LR的工作原理,它是录制客户端的活动,客户端与服务器端采用什么“通讯协议”,录制时就采用什么协议,所以方案一采用单协议的HTTP协议。二、因为客户端要嵌入ACTIVX控件,考虑到ACTIVX控件采用的一般都是COM/DCOM协议,所以录制的时候采用多协议(HTTP和COM/DCOM)方式。

        录制和运行、分析的过程就不说了,说一下结果,采用单协议HTTP录制、运行、分析的结果都非常好,代码的易读性也非常。所以如果是WEB方式,包括页面有ACTIVX控件,一般采用HTTP单协议就可以了。但有些虽然是WEB方式的,如网上视频类的,你还是要采用多协议。

  • 谈谈软件测试的前景

    2008-07-07 11:57:34

    目前很多做测试的人员对测试的前景很迷茫,不知道自己到底该不该在测试行业发展,往什么方向发展。我结合我遇到的一些情况,谈谈自己的一些看法,一家之言而已。我认为,以后无论是软件还是测试都将走向服务,以服务的思想来指导我们的工作,必将会有很大的收益和发展。

    案例一:我在一家大型企业做项目的时候,他们信息中心的技术人员请求我帮他们做几件事情,一件是他们已经运行一年多的一个系统把操作系统从win2000 server改为win2003 server后,运行了一段时间后,系统崩溃了,他们不知道原因,他们也没办法评价,以后如果应用系统移植会不会还发生这样的原因,他们管理的应用软件大概有50多个;另一件是他们运行的一个办公自动化系统(OA)现在运行速度越来越慢,他们和开发人员一起费了很大功夫,找不到事情的原因;还有一件是他们上了一套数据库负载均衡系统,但他们不知道如何来测试。从上面几件事情可以看出,第一件是安装配置测试与压力测试相结合的一个案例,经过性能测试发现应用系统中采用的部分第三方控件在win2003 server下支持的不好,在用户访问量比较大的情况下造成了内存溢出。第二件采用性能测试,发现文件浏览、文件批复模块功能的相应时间比较慢,但WEB服务器和数据库服务器的CPU占用率和内存占用率都不大,网络带宽也能满足要求,初步确定是系统设计方面的原因,并且听用户说刚上线的时候速度还可以,初步判断可能是和数据库设计有关系,进入数据库一看,有两个经常访问的数据表没有建立索引,并且每天每个表都要增加近2000条记录,建立索引后,访问速度明显提高。第三件事情,我采用的是两步走,第一步用测试工具录制一个数据的添加、修改、删除程序,利用数据驱动,访问数据库,得到的结果是成功的。第二步采用多用户并发访问数据库,结果失败。从以上案例来说,大型公司的应用越来越多,而他们的管理人员还不具备各种测试知识,这部分是软件测试公司应该发展的一个重要方向。也应该是一个很大的空间。

    案例二:还是上诉的那家企业,该企业有ERP、EHR、OA、财务软件、其他专业应用软件,各种开发语言,各种数据库,为软件的应用、维护、管理都带来了很大的困难,并且各种信息都没办法充分利用和共享,造成了一个个信息孤岛,也造成了大量的数据冗余。现在不是缺少应用系统而是如何充分利用这些系统和数据。可以断言,新的应用系统还会源源不断地进入,如何为以后的发展提供更好的接口,这都需要咨询、测试专业的人员来认真考虑的事情。

    以后必将是服务的天下,SOA的发展可能会真的带来一场革命。

Open Toolbar