淘宝商城(天猫)高级技术专家.3年研发+3年性能测试调优/系统测试+4年团队管理与测试架构、研发系统实践. 新舞台新气象, 深化测试基础架构及研发架构,希望能在某个技术领域成为真正的技术大牛。欢迎荐才http://bbs.51testing.com/viewthread.php?tid=120496&extra=&page=1 .邮件: jianzhao.liangjz@alibaba-inc.com,MSN:liangjianzhao@163.com.微博:http://t.sina.com.cn/1674816524

发布新日志

  • [论坛] 一次性能测试结果排查过程

    2009-02-13 01:09:28

    一个测试环境受到外部不预期的干扰,性能测试结果将出现不预期的数据,导致分析困难甚至错误结论。
    最近碰到一个CASE,将一个sevice  插入测试环境的网站应用中,然后对比是否加入这个service的性能影响。
    多台测试机器,每台机器部署多个应用,所有应用共享一个DB。

      系统架构: java + webx+ ibatis+ oracle。

            另外,这个service采用几百K的数据运行速度也在毫秒级别。
           
            呵呵,差点掉到沟沟里,特记录下。
           
    一 制定测试方案

    和service开发的dev 评审测试方案。 没有和网站应用的架构师核对。
    被测服务器 load 已经大于 1 。


    二 性能测试执行过程

    选取一个post 产品的流程做性能测试脚本。性能测试数据从几百个byte-几K.
    调整JAVA应用参数与生产环境同。

    1) 删除用户数据
    2) 删除日志
    3) 重启应用
    4)交替执行service上与不上场景.
    5)多次执行去性能数据平均值

    性能测试选择在晚上人少时执行。


    三 性能测试结果分析

    性能测试发现average response time,上与不上service 相差无几,都是0.13秒左右 。甚至同样并发数时,上service的response time 比不上service的response time还要低。
    其他load <2 ,cpu%约20% ,iowait% <1%,内存充足都相近。这个结果似乎有点解释不通。

    另外比较反常的是:average reponse time图(非graph average)上偶尔有锯齿型的到达0.2 甚至0.4的高点,尺度延续时间40多秒。average response time的 std dev(标准方差)约 0.13甚至更高。
    经web page break down分析图片这个数据更加清晰可见。


    经咨询网站的同事,架构师,DBA,可能多台机器上有应用定时器(quartz框架)或者DB自身定时器干扰,与网络无关。
    选择关闭上述所有应用定时器以及DB层定时器后,晚上重新执行多个场景的性能测试,并手工定期检查DB执行SQL。


    再分析性能测试结果,依然有锯齿型数据且性能结果且很接近之前结果,但这个数据是可控程度高的数据。
    用SQL查询性能测试期间DB 日志:
    select SEQUENCE#,FIRST_TIME from v$log_history
      2  where
      3  FIRST_TIME >=to_date('20090209 19:00:00','yyyymmdd hh24:mi:ss')
      4  and FIRST_TIME<to_date('20090209 23:00:00','yyyymmdd hh24:mi:ss')

    发现有4个日志切换过程。

    对比average reponse time拐点与日志切换时间点,部分与之吻合,但average reponse time拐点长度偏大。
    经咨询每次日志切换约有20-50毫秒事务挂起。

    另外部分不吻合部分,是service处理数据长度随机变化有关。

    四 常见工具

    再回头看看确认环境干净,参数配置预期正确的工具。

    毫无疑问,好用的脑子是最强的武器。

    1) OS 层面
    ps ,top 看进程
    ipcs    看进程间通讯
    netstat 看网络连接
    nmblookup,nbtstat 连接的人

    sysctl,/proc  看系统参数
    ulimit   系统软、硬限制

    2)apache 层

    httpd.conf

    3) mod_jk 层
    几个 property文件

    4)JBOSS 层
    run.conf,run.sh以及应用配置参数

    另外就是检查对应启动的服务,可以借助 web-console
    5) JVM 参数

    6) DB 层面
    oracle init file
    mysql show variables

    7) 其他关联服务。
    如 memcached

    ...

    从上例看到,性能测试排除干扰很重要,在系统日趋复杂的情况下需勤开口、善借外力,力争一次把事情做对、做好

    [ 本帖最后由 liangjz 于 2009-2-13 01:06 编辑 ]
  • Windows下远程运行LINUX 上jmeter GUI解析监视器数据

    2008-12-05 22:51:38

    Windows 内存不足,JMeter解析大量监视器数据导致OutOfMemory异常,故利用8G内存的LINUX机器上JVM解析jmeter  监视器数据。 LINUX无显示器连接。

     

    所以需要Windows下远程运行Linux图形界面,工具有Xming或者Xmanager等。

    更多参考:http://www.cs.nctu.edu.tw/help/xming.html

    1.1    下载XMing 安装在Windows

    http://sourceforge.net/projects/xming

    安装XMing

    1.2    检查LINUX  图形包

    [aranda@dc_14 ~]$ rpm -qa |grep xorg
    xorg-x11-server-utils-7.1-4.fc6
    xorg-x11-server-Xnest-1.1.1-48.41.el5

    1.3    Windows下启动XMing launch

    XMingSSH 连接环境下选择no  access control,则不必做额外的动作。

    1.4    LINUX shell上设置DISPLAY输出到WINDOWS

     

    export DISPLAY=客户端IP:0

     

     

    1.5    LINUX 上测试GUI

    Xclock

    ./jmeter.sh 起动jmeter

  • 阿里巴巴性能测试规划思路

    2008-11-14 00:14:37


    1)充分利用已有性能测试脚本,做性能测试回归对比,形成性能测试结果趋势分析库
    2)补充JMeter LINUX/ORACLE监控功能,补充报表统计分析功能,增强分布式脚本分发功能,规避OutOfMemory异常
    3)进一步挖掘前端性能测试工具,记录生产环境页面响应时间变化趋势,利用浏览器上等图形展现框架表达趋势。另外,参考HP BAC产品开发一些补充功能
    4)公司级别日志挖掘功能,以及服务器端性能监控颗粒细化,公司多个PC机器访问时间等信息充分利用,完善生产环境负载模型
    5)最最重要的是,提高模拟海量数据/高并发模拟压力能力,避免系统上线性能问题。还需要利用JMX等技术开发监控JAVA服务器/apache 细颗粒的性能,
    降低性能调优难度
    6)性能测试人才梯队建设以及培训交流增强
  • Jmeter图形化框架

    2008-08-10 14:54:48

    最近在看Jmeter源代码,顺便温习JAVA SwingAPI

     

    为了看得更清楚Jmeter图形化处理,偶尽量剥离Jmeter相关的API ,使用SUN JAVA API

     

    更多请参考经典的JAVA书籍:《Java 2核心技术》。偶的JAVA知识从这2本书开始J

     

    最核心的技术点:

    Ø         JframeJPanel 等容器

    Ø         ActionListener 事件处理

    Ø         ImageIcon 图片展现

    Ø         反射,如commandClass.newInstance

     

     

    package org.apache.jmeter;

    import java.awt.BorderLayout;

    import java.awt.Color;

    import java.awt.Component;

    import java.awt.Container;

    import java.awt.Dimension;

    import java.awt.GridLayout;

    import java.awt.HeadlessException;

    import java.awt.Point;

    import java.awt.event.ActionEvent;

    import java.awt.event.ActionListener;

    import java.awt.event.KeyEvent;

    import java.awt.event.MouseAdapter;

    import java.awt.event.MouseEvent;

    import java.lang.reflect.Modifier;

    import java.util.HashMap;

    import java.util.HashSet;

    import java.util.Iterator;

    import java.util.List;

    import java.util.Map;

    import java.util.Set;

     

    import javax.swing.BorderFactory;

    import javax.swing.Box;

    import javax.swing.BoxLayout;

    import javax.swing.ImageIcon;

    import javax.swing.JButton;

    import javax.swing.JComponent;

    import javax.swing.JDialog;

    import javax.swing.JFrame;

    import javax.swing.JLabel;

    import javax.swing.JMenu;

    import javax.swing.JMenuBar;

    import javax.swing.JMenuItem;

    import javax.swing.JOptionPane;

    import javax.swing.JPanel;

    import javax.swing.JScrollPane;

    import javax.swing.JSplitPane;

    import javax.swing.JMenu;

    import javax.swing.JMenuBar;

    import javax.swing.KeyStroke;

    import javax.swing.SwingUtilities;

    import javax.swing.border.EmptyBorder;

     

    import org.apache.jmeter.gui.action.Command;

     

    //为了事件处理,实现ActionListener

    public class JFrameTest extends JFrame  implements ActionListener {

        private Map commands = new HashMap();

        private Map preActionListeners = new HashMap();

        private Map postActionListeners = new HashMap();

        JDialog about = null;

       

        //actionPerformed事件处理入口

        public void actionPerformed(final ActionEvent e) {

           SwingUtilities.invokeLater(new Runnable() {

               public void run() {

                  performAction(e);

               }

     

           });

        }  

        //加入命令映射器

        //核心代码就是反射技术

        private void populateCommandMap() {

           List listClasses;

           Command command;

           Iterator iterClasses;

           Class commandClass;

           try

           {

           commands = new HashMap(1);

           commandClass = Class.forName("org.apache.jmeter.gui.action.AboutCommand");

            if (!Modifier.isAbstract(commandClass.getModifiers())) {

                command = (Command) commandClass.newInstance();

                Iterator iter = command.getActionNames().iterator();

                while (iter.hasNext()) {

                    String commandName = (String) iter.next();

                    Set commandObjects = (Set) commands.get(commandName);

                    if (commandObjects == null) {

                        commandObjects = new HashSet();

                        commands.put(commandName, commandObjects);

                    }

                    commandObjects.add(command);

                }

            }

           }catch(Exception e)

           {

               e.printStackTrace();

           }

          

        }

        /**

         * Allows an ActionListener to receive notification of a command being

         * executed prior to the actual execution of the command.

         *

       

  • MSXML6 SDK解析中文XML文件

    2008-08-10 01:36:58

    1.1       下载msxml6_SDK.msi安装

     

    http://www.microsoft.com/downloads/details.aspx?familyid=993C0BCF-3BCF-4009-BE21-27E85E1857B1&displaylang=en

     

    默认安装在C:\Program Files\MSXML 6.0\

     

    1.2       vc6上建立编译环境

    Preprocessor 编译加入 Additional include directorie加入C:\Program Files\MSXML 6.0\inc

     

    LINK module加入: msxml6.lib

     

    Link Additional  library path加入:C:\Program Files\MSXML 6.0\lib

    1.3       解决vc6 link错误问题

     

    msxml6.lib(msxml6_i.obj) : fatal error LNK1103: debugging information corrupt; recompile module

     

    参见

    http://www.armleg.com/forum/viewtopic.php?p=388&sid=414fd259dcf02a90f150708296924178&mforum=diodiaforum

     

    All I get from Google is that VS6 doesn't work with platform SDK's later than february 2003.

     

    必须采用release版本编译、链接才成功。(build->set active project configuration->win32 release)

     

     

    1.4       汉语问题

     

           //解决汉语问题

           setlocale(LC_ALL,"chinese-simplified");

     

    1.5       源代码

     

    #include <objbase.h>

    #include <msxml6.h>

    #include <stdio.h>

    #include <windows.h>

    #include <stdarg.h>

    #include <locale.h>

    #include <AtlBase.h>

     

    #import <msxml6.dll> raw_interfaces_only

     

    // Macro that calls a COM method returning HRESULT value:

    #define HRCALL(a, errmsg) \

    do { \

        hr = (a); \

        if (FAILED(hr)) { \

            dprintf( "%s:%d  HRCALL Failed: %s\n  0x%.8x = %s\n", \

                    __FILE__, __LINE__, errmsg, hr, #a ); \

            goto clean; \

        } \

    } while (0)

     

    // Helper function that put output in stdout and debug window

    // in Visual Studio:

    void dprintf( char * format, ...)

    {

        static char buf[1024];

        va_list args;

        va_start( args, format );

           sprintf(buf, format, args);

        vsprintf(buf, format, args );

        va_end( args);

        OutputDebugStringA( buf);

        printf("%s", buf);

    }

     

    // Helper function to create a DOM instance:

    IXMLDOMDocument3 * DomFromCOM()

    {

       HRESULT hr;

       IXMLDOMDocument3 *pxmldoc = NULL;

     

       HRCALL( CoCreateInstance(CLSID_DOMDocument60,

                      NULL,

                      CLSCTX_INPROC_SERVER,

                      //__uuidof(IXMLDOMDocument),

                                  IID_IXMLDOMDocument3,

                      (void**)&pxmldoc),

                      "Create a new DOMDocument");

     

        HRCALL( pxmldoc->put_async(VARIANT_FALSE),

                "should never fail");

        HRCALL( pxmldoc->put_validateOnParse(VARIANT_FALSE),

                "should never fail");

        HRCALL( pxmldoc->put_resolveExternals(VARIANT_FALSE),

                "should never fail");

     

        return pxmldoc;

    clean:

        if (pxmldoc)

        {

            pxmldoc->Release();

        }

        return NULL;

    }

     

    int Get_nodeValue(IXMLDOMElement * pRoot , char * tagName,char *ret_text)

    {

           USES_CONVERSION;

        IXMLDOMNodeList  * pNodeList = NULL;

           IXMLDOMNode  * pNode = NULL;

           HRESULT hr;

           BSTR bstr = NULL;

     

           hr=pRoot->getElementsByTagName(_bstr_t(tagName),&pNodeList) ;

           if (FAILED(hr))

                  return -1;

     

           //取第一个满足条件的

           hr= pNodeList->get_item(0,&pNode);

           if (FAILED(hr))

                  return -1;

          

           hr=pNode->get_text(&bstr);

           if (FAILED(hr))

                  return -1;

           //dprintf("v=%s\n",W2A(bstr));

           sprintf(ret_text,W2A(bstr));

           return 0;

    }

     

    int main(int argc, char* argv[])

    {

      /*

      HRESULT hr;

      IXMLDOMDocument3 *pXMLDoc = NULL;

      CoInitialize(NULL);

      hr = CoCreateInstance(CLSID_DOMDocument60,

                         NULL,

                         CLSCTX_INPROC_SERVER,

                         IID_IXMLDOMDocument3,

                         (void**)&pXMLDoc);

       if (FAILED(hr))

       {

          printf("Error code: %x\n", hr);

       }

    */

           USES_CONVERSION;

        IXMLDOMDocument3 *pXMLDom=NULL;

        IXMLDOMParseError *pXMLErr=NULL;

        BSTR bstr = NULL;

        VARIANT_BOOL status;

        VARIANT var;

        HRESULT hr;

           IXMLDOMElement * pRoot = NULL;

           VARIANT_BOOL isHasChild=VARIANT_FALSE;

           long listLen=0;

           long i=0;

           char ret_scrīpttext[48]={0};

           char ret_steptime[48]={0};

           char sz_xmlFile[]="lr.xml";

          

        CoInitialize(NULL);

           //解决汉语编码问题

           setlocale(LC_ALL,"chinese-simplified");

     

        pXMLDom = DomFromCOM();

        if (!pXMLDom) 

                  goto clean;

          

        VariantInit(&var);

        V_BSTR(&var) = SysAllocString(_bstr_t(sz_xmlFile));

        V_VT(&var) = VT_BSTR;

        HRCALL(pXMLDom->load(var, &status), "");

     

        if (status!=VARIANT_TRUE) {

            HRCALL(pXMLDom->get_parseError(&pXMLErr),"");

            HRCALL(pXMLErr->get_reason(&bstr),"");

            dprintf("Failed to load DOM from stocks.xml. %S\n",

                        bstr);

            goto clean;

          

     

        }

        HRCALL(pXMLDom->get_xml(&bstr), "");

     

        dprintf("XML DOM loaded from stocks.xml:\n%S\n",bstr);

     

           HRCALL( pXMLDom->get_documentElement(&pRoot) ,"get_documentElement");

      

           Get_nodeValue(pRoot,"scrīpt",ret_scrīpttext);

           Get_nodeValue(pRoot,"steptime",ret_steptime);

          

           printf("%s %d",ret_scrīpttext,atoi(ret_steptime));

     /*

        HRCALL(pNode->get_nodeValue(&value),"get_nodeValue");

           USES_CONVERSION;  

        dprintf("v=%s\n",OLE2A(value.bstrVal));

           SysFreeString(bstr);

    */

     

    clean:

        if (bstr) SysFreeString(bstr);

        if (&var) VariantClear(&var);

        if (pXMLErr) pXMLErr->Release();

        if (pXMLDom) pXMLDom->Release();

     

        CoUninitialize();

        return 0;

    }

     

    Lr.Xml文件如下(notepad保存为ascii格式)

    <?xml version="1.0" encoding="GB2312"?>

     

    <root>

        <scrīpt type="string">d:\工程\1.lrr</scrīpt>

        <steptime>30</steptime>

    </root>

  • win32 下解决数字四舍五入问题

    2008-08-04 20:43:38

     

    今天在windows下用vc6 编写一程序,需要做四舍五入。
    想到c99标准有round函数。可以很遗憾编译成功,LINK出错:
    Linking...
    run.obj : error LNK2001: unresolved external symbol _round
    run.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.

    google的结果发现: round was added to C in the C99 standard. Microsoft still hasn't finished putting support for C99 in the compiler and round isn't in there yet.

    下面函数运行成功。


    #include  <stdio.h>
    #include <math.h>
    double Round(double num,int bit);
    int main()
    {
     printf("%f\n",Round(-100.5,0));
     printf("%f\n",Round(100.5,0));
     return 0;
    }

    //bit位数

    double Round(double num,int bit)
    {
     return floor( num * pow( 10 , bit ) + .5 ) / pow( 10 , bit );
    }
     

     

  • [论坛] 自动化友好、干净停止loadrunner运行场景的源代码

    2008-08-01 23:18:36

    最近针对loadrunner做功能扩展,其中一个环节是:尽力正常点击stop停止,如经过处理无法停止,则干净终止loadrunner进程。

      loadrunner手册有命令行方式启动wlrun.exe进程的方式,但没有停止wlrun.exe的方式。本方法用win32实现友好停止Loadrunner场景。

      窗口层次关系可以用spy++察看 .

      测试程序的方法,启动一个loadrunner运行场景。

    #include &lt;stdlib.h&gt;
    #include &lt;stdio.h&gt;
    #include  &lt;time.h&gt;
    #include  &lt;errno.h&gt;
    #include &lt;locale.h&gt;
    #include &lt;windows.h&gt;
    #include &lt;vdmdbg.h&gt;


    typedef struct
       {
          DWORD   dwID ;
          DWORD   dwThread ;
       } TERMINFO ;

      BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;


    DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )
       {
          HANDLE   hProc ;
          DWORD   dwRet ;

          // If we can't open the process with PROCESS_TERMINATE rights,
          // then we give up immediately.
          hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,
             dwPID);

          if(hProc == NULL)
          {
             return FALSE ;
          }

          // TerminateAppEnum() posts WM_CLOSE to all windows whose PID
          // matches your process's.
          EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;

          // Wait on the handle. If it signals, great. If it times out,
          // then you kill it.
          if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)
             dwRet=(TerminateProcess(hProc,0)?TRUE:FALSE);
          else
             dwRet = TRUE ;

          CloseHandle(hProc) ;

          return dwRet ;
       }


    BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam )
    {
      DWORD dwID ;

      GetWindowThreadProcessId(hwnd, &dwID) ;

      if(dwID == (DWORD)lParam)
      {
         PostMessage(hwnd, WM_CLOSE, 0, 0) ;
      }

      return TRUE ;
    }

    //MyEnumWindow 函数本身只能枚举最top-level的窗口。
    //嵌套的窗口自己枚举

    //这里用spy++观察层次结构
    //模拟用户鼠标操作停止loadrunner的过程
    BOOL   CALLBACK    MyEnumWindow(HWND   hWnd,   LPARAM   lParam)
    {
       char    sz_text[MAX_PATH]={0};  
       int  len =0;
       char  * p_title = NULL;
       int  ret;
       HWND child_hWnd=NULL,dialog_hWnd=NULL,next_hWnd=NULL;
       int  i=0;
       BOOL isFound = FALSE;
       int try_time=10;
       WINDOWINFO  winInfo;
       DWORD dwID ;
       p_title=(char*)lParam;

       len= GetWindowText(hWnd,   sz_text,   sizeof(sz_text)/sizeof(sz_text[0]));   
       if (strstr(sz_text,"LoadRunner"))
            printf("%s\r\n",sz_text);  
       child_hWnd = hWnd;
       if(strstr(sz_text,p_title))   
       {   
          
       while(1)
       {
        //获取子窗口
        child_hWnd=GetWindow(child_hWnd, GW_CHILD);
        //恶意关闭loadrunner时,窗口是否为存在?防止死循环。
        if(child_hWnd!=NULL)
        {
         len= GetWindowText(child_hWnd, sz_text, sizeof(sz_text)/sizeof(sz_text[0]));      
         if (!strcmp(sz_text,"&Start Scenario"))
         {
         //获取兄弟窗口
         next_hWnd=GetWindow(child_hWnd, GW_HWNDNEXT);
         len= GetWindowText(next_hWnd,sz_text,   sizeof(sz_text)/sizeof(sz_text[0]));
         if (!strcmp(sz_text,"S&top") )
         {
          //找到停止的窗口
          isFound =TRUE;
          break;
         }   
         }
        }
        else   //child_hWnd!=NULL
        {
        break;
        }
       } //while

       
       if (FALSE ==isFound )
       {
        //失败退出
        printf("not found S&top!\r\n");
        return TRUE;
       }

       //尝试投递try_time次。
       //for(i=0;i &lt; try_time; i++)
       while(1)
       {

        //SendMessage(next_hWnd,  BM_CLICK,0,  0);
        PostMessage(next_hWnd,  BM_CLICK,0,  0); // 这里不能用SendMessage,否则阻塞进程
        dialog_hWnd  = FindWindow("#32770", "LoadRunner Controller");
       
        if (!dialog_hWnd)   
        {
         printf("Find dialog error.  ret=%d\r\n",GetLastError());
        }
        else  
        {      
         //if  (IsWindowVisible(dialog_hWnd))
         //{
          len= GetWindowText(dialog_hWnd,  sz_text, sizeof(sz_text)/sizeof(sz_text[0]));
          printf("GetWindowText  return %s\r\n",sz_text);           
          //查找对话框上按纽
          child_hWnd  =  FindWindowEx(dialog_hWnd,0,"Button","确定");
          if (!child_hWnd)
          {
           printf("确定 button  ret=%d\r\n",GetLastError());
           continue;
          }

          SendMessage(child_hWnd, BM_CLICK,0,  0);
          ret = GetLastError();
          if (ret)
          {
           printf("button  error. ret=%d\r\n",ret);
          }
          else
          {
            printf("正常停止loadrunner!\r\n");
          }
           //经过如上处理后
          printf("destroywindows\r\n");
           Sleep(10);
           //强行关闭loadrunner相关进程
             GetWindowThreadProcessId(hWnd, &dwID) ;
          TerminateApp(dwID,10);
          return   FALSE;   
         //}
        } //(!prev_hWnd)
       }//for
       }  

       return   TRUE;   
    }
    int stop_loadrunner()
    {

      char    sz_title[]="Mercury LoadRunner Controller ";
      //  char    sz_title[]="S&top";
      if (EnumWindows(MyEnumWindow,(long) sz_title) )
        printf("failed,errno=%d",GetLastError());

    }


    void main()

    {

    stop_loadrunner();

    }
  • [论坛] 电信网管系统编写DLL API供loadrunner调用的规范

    2008-07-05 23:16:25

    由于性能脚本开发工具一些固有的缺陷,加上网管系统多用事件触发,压力入口存在多个,录制采用的协议相对底层(非web),解决回放的成本高。
         故将前台用户操作部分的核心功能封装成纯C语言的dll,供loadrunner调用,具体要求:
    (1)将存在度量用例响应时间的程序段(存在用户等待的地方),封装成一个 dllexport function(in 变化参数,out 结果代码,out 错误消息)函数。in参数不用二维数组、函数指针等复杂类型。多用一维数组,字符串,指针,int/long等简单类型。in参数为界面上看到的友好名称或者能轻易从数据库查询出来的值。
    (2)若为触发的事件,外部调用能控制等待或者轮循的速率控制。 如sleep...
    (3)对于回调的事件,有专门的函数收包,可以不审核包的内容。
    (4) 对核心函数应该提供调用样例。如
    init(..);
    login(user,passwd.....);
    getalert(...)
    cofirmalert(...)  
    logout(..);
    注意参数都是对客户而言是友好的,非下层corba或者socket等私有key.
    若后台网元传送到采集机/服务器无法模拟峰值吞吐的 ,同样有如上要求。
    如何客户端主动发送的请求与服务器推送的告警所用端口分开,请说明两个端口。
    若核心程序为Java包,则请封装为JAR,暴露核心功能class以及方法。   

    另外,请厂家利用viso描述核心功能在采集机、应用服务器、DB之间的信息流图.

    [ 本帖最后由 liangjz 于 2008-7-5 23:20 编辑 ]
  • [论坛] loadrunner的不足与jmeter用武之地

    2008-06-20 22:08:49

    我们购买了LoadRunner 8.1 作为性能测试主流工具,商业工具确实用的蛮好的,在部门层面推行顺利。
    结合实践,发现有几点相当不错:

    1) LoadRunner controller运行稳定
    2) 支持多个load generator 一起施加压力
    3) 监控指标相对齐全
    4) 性能测试结果颗粒细致
    5) 预留有性能结果在monitor上的api 接口
    ...

      但LoadRunner是否足够完美了呢?答案:NO

    1) 对汉语的编码支持问题:utf-8/gbk设置导致有时仅用英文作web_reg_find的check point

    2) LoadRunner 8.1 Udp方式监控unix资源导致有断续, 呵呵,改天要电话咨询下HP有无补丁。
    (LR 8.0有的)

    3) 有时应用vugen 录制/回放异常退出程序

    4) 最为诟病的:昂贵

    5) 支持jboss/tomcat/mysql等的应用性能数据需要自己实现,实际上监控linux也无可用内存、iowait%、网络流量等指标

    ...

      我们把更多眼光关注开源社区,评估opensta、jmeter、webload...。 最终选取与公司主流技术平台( java+apache2+ jboss4.2 +oracle9i/10g + redhat linux)一致的jmeter做一个补充。

      对于Jmeter最为关键的几步:

    1) 分析性能测试结果和loadrunner不同的原因
    2) jmeter 产生压力的稳定性以及原理
    3) 监控扩展能力。 linux+oracle9i+jboss+mod_jk 等这些需要支持,呵呵,否则很可能需要手工收集各个平台性能数据,造成效率低下
    4) jmeter脚本调试能力,支持参数化、关联、检查点、http协议自主控制(超时、cookie、http头、是否下载non-html资源)等
  • [论坛] 容量规划问题列表,期待专家深入交流

    2008-06-15 21:44:20

    沙龙交流前自己准备的容量规划方面的问题列表,呵呵,也期待业界这方面的专家指点。

    1 瓶颈资源到达75%以后,容量预测偏差难以衡量,预测准确率陡降。
    现有容量规划软件包容这种情况?或者如何做能提升这个区域的预测准确度

    2 SAP 的容量规划工具可容忍偏差范围多大?
    3 SAP 内部有自己的监控软件么?包括应用级别的监控。

    现在的软件更多针对应用服务器、web server和os层面的监控,但对应用本身的监控是缺乏的

    假如没有这些细粒度的监控数据,SAP 如何更好为用户行为建模?

    4 SAP 容量规划软件建模算法是什么?是否为排队网络?

    可以调整客户到达分布与服务时间分布等参数?

    5 BELL实验室网络测试发现,用长相关或自相似随机模型比排队网络模型更符合web 网站客户到达分布? SAP 容量规划软件针对更合适的模型做调整么?

    6 SAP 容量规划软件内部有what-if 假设分析么?直接支持针对内存或者硬盘的what-if分析?

    7 SAP 针对跨机型的容量规划如何做?

    尤其是sun公司不参加TPCC评估后的机型 。

    8 如何做容量规划效果的反馈

    9 做容量规划的团队组员有几个,都是怎么样的专业背景(数学?计算机?)

    10 开源容量建模工具要求手工采集非常多数据,必然引入较大的误差?对于这种状况,有何建议


       经过和SAP 工程师交流。负责容量规划的工程师和负责测试的不属于同一个部门,容量规划工程师面对咨询公司,提供硬件建议。

      国内的SAP工程师更多是规划软件的应用者。SAP 软件相对成熟,且部署的机型相对单一。目前容量规划结果满足需求。
      
      SAP有商业逻辑的监控。SAP容量规划软件采集生产系统数据建模,在web页面上输入参数,降低建模门槛。目前SAP容量规划软件建模依赖经验值,而非各种复杂的数学模型。当下没有必要研究开源建模工具。

      SAP软件用内部开发的语言开发的。有很好的扩展性。
       
      由于上述背景,我自己碰到的一些问题就没有很深入交流。

      目前阿里巴巴需要自己建立模型,并需要长期校准模型,另外由于需求、应用的多变,容量规划的门槛依然需要具备较高的数学建模与计算机性能分析方面的背景。
  • [论坛] 容量规划沙龙4原则以及个人理解

    2008-06-15 01:18:08

    个人觉得今天容量规划沙龙最核心内容即4原则

    1)经过良好调优的系统才容量规划
    2)可扩展性好的系统才做容量规划
    3)人人有容量规划意识。执行T-shirt sizing是一个巨大进步
    4) 最关键的事情是测量

    其他的还有
    5) 用真实的产品数据做容量规划
    6) 特别区分对待的容量规划场景
    7) 追求响应时间与成本间平衡

      欢迎其他朋友补充。

    以上的点说得都很实在。
    根据自己的实践做一个发散说明

    1)容量规划有一个难点:在系统扩容和调优之间取得平衡。
    就是停止调优的标准是什么?

    目前我是根据经验值判断特定的硬件、配置参数支撑一定的访问模式、数据量、并发数、吞吐率且满足响应时间等SLA指标。 另外,检查系统不存在core dump或者大量连接超时,日志无异常等。
    有较大的主观性。

    2) 系统扩展性良好。

    根据了解,SAP 没有结合性能测试做系统的可扩展性判断。呵呵,也许SAP架构很多年稳定了,没有必要做这个事情。

    我们实践中,会设置多个场景执行性能测试或者了解系统架构判断。
    如是否采用多线程技术?集群是否采用session技术?

    建模采用的数学模型一般有很多的假设,就是公式成立有很多前提条件。性能测试需要判断结果是否违背了假设。同样预测时,也需要判断是否背离假设

    3) 人人容量规划意识

    从阿里巴巴的角度看,应该是从架构设计权衡系统扩展性、开发加入代码性能探针、性能测试判断是否该停止调优、运维部门长期跟踪反馈性能监控数据以及采购规划、数据仓库平台采集PV、运营部门预测下一年业务增长速度等多个环节。

    据目前看,要走的路还很长。
    对阿里巴巴而言,在网站购买的大量便宜的PC server背景下,容量规划的收益与成本不是足够一目了然,以及资源紧缺是最头大的问题。

    与前同事聊天,目前广东电信研究院的容量规划的驱动力不足是当下最头痛的事情。


    4) 第四个观点:测量是最关键的。


    这个论点放到阿里巴巴。我个人有不同的看法。
    测量是很重要。个人认为借助测量到的数据,如何构造一个合理的容量模型、如何校准模型符合实际情况更关键,否则预测的结果偏差过大导致没有太多的参考价值。

    另外,目前的商业工具或者开源工具都存一些不足,如何对工具做二次开发完善,也是一件很有挑战性的工作。
  • [论坛] 容量规划工具

    2008-06-14 23:45:51

    1 开源
      java model tool
      pdq

    2 借用定律

    A
      little's  law
                 N = X * R

    N = Number of requests in the system
    X = Throughput
    R = Response Time

    B  Utilization law

    U = X * S

    U = Utilization
    X = Throughput
    S = Service Time

    c Stretch Factor

    Stretch Factor=1/ (1-U) =response time/service time

    where U is the utilization of the server.
    The analytic formula for estimating stretch factor assumes the following:
    There are an infinite number of customers
    The arrival times are exponentially distributed
    The service times are exponentially distributed


    3 商业工具
    teamquest,国外SUN 公司、国内广东电信研究院用
    bmc performance assurance,上海电信研究院用
    原来Mercury工具也和一厂商有容量规划工具的合作的现在没有了

    其他的请各位朋友补充
  • rails应用性能测试技巧以及工具

    2008-04-27 11:18:04

    其他web应用也可以参考 。

    相当多概念思路可以遵循

    http://bbs.51testing.com/viewthread.php?tid=113200&page=1&extra=page%3D1

     

  • 学习loadrunner性能测试建议路线图

    2008-03-19 23:02:41

  • 扩展LoadRunner功能的一种实现思路

    2008-03-19 22:57:14

    http://bbs.51testing.com/viewthread.php?tid=108978&pid=916421&page=1&extra=page%3D2

    由于时间关系,没有来得及实现。呵呵,供各位碰到同类问题的同学参考。

       具体的实现思路可以和我再交流.
        附件提出一种比较复杂的协议的扩展思路 。

       

  • mysql+solaris 上的性能诊断过程

    2008-03-11 22:06:46

  • [论坛] 在电信时写的脚本编写的一些基本要求

    2008-03-11 21:57:25

    脚本能有效模拟用户行为,是产生系统压力的关键。脚本关键要求是可迭代、并发运行,更详细要求至少包含:

    (1)需要度量用户等待的步骤,应加入事务(transaction)

    (2)事务命名:用例名_步骤名

    (3)需要用户输入的地方,必要时加入参数化(parameter)。一般为一个VUSER准备4条以上的数据

    (4)加入必要的校验点( checkpoint)

    (5)若后一步骤的输入依赖于前面步骤的输出,应该建立关联(colleration)

    (6)脚本行为与用户行为一致,与文档操作步骤一致

    (7)最好选取数据适中的区域,若不确信,请选取数据集中的区域

    (8)动态变更的数据若不能通过用户输入或者服务器返回获取,请变更流程适应测试。如随机动态图片上的校验码。

        为了最大程度复用脚本,请严格依照以上步骤执行。同时,我们在获取脚本后,会增加进一步的验证点。

        另外,请在评测中心校验或者开发脚本期间,派熟悉涉及模块的程序员到现场技术支持。







    检查点一般

    (1)安装 ethreal截获网络包,对比loadrunner录制的数据流

        确保不遗漏压力。



    (2) insert/update/delete 业务回放脚本,然后通过应用界面检查或者通过sql查询。

       对于查询类,可以在服务器安装tcpdump 截获client网络包,检查sql



    (3)询问业务错误的特征码,在脚本中注册错误码



    (4) 检查参数化属性是否符合业务需求



    (5)回放脚本,最好把extend log打开,观察有无error,mismatch

    或者 http 1.1 500/400等关键词
  • loadrunner缺陷

    2008-03-11 21:43:54

  • [论坛] 性能测试讨论专题

    2008-03-01 00:37:21

    也蛮有些时间了。


    一    生产系统性能吞吐率的准确度

             部分网站有XX部门采集PV 数据,但这个PV与我们更关心的业务吞吐率不完全Match, 而且由于apache  mod_rewrite 作了URL改写,给我们分析网站业务吞吐率带来很大困难


    二   测试环境硬件与生产系统相差甚远,测试结果给生产环境的参考意义存疑

            数据库硬件差异最明显,生产环境多采用ibm  p 系列小型机, 而测试环境 数据库多为PC Server。 有时本想测试部署在jboss上的应用性能,但数据库先到达了瓶颈,无法带来有效压力  

          另外,比较突出的一些差异:集群、 专用邮件服务器、图片服务器, 这一部分测试环境也很难模拟。

    三   测试系统与生产系统数据量级差异,给整体性能带来很大的影响

                  同样由于硬件缘故或者由于数据保密缘故。  这个影响在多个系统得到验证

    四    如何快速进行系统调优


           面对众多框架、组件,以及复杂的业务应用。 如何在有限的时间内漂亮地将系统性能调整到一个能接受的范畴,需要协调多方资源。
  • [论坛] 某季度性能测试REVIEW,希望能给TEAM LEADER一些帮助

    2008-03-01 00:31:38

    蛮有些时间的一个小结,希望能给team leader一个启发


    1 小组

       积极引导组员了解性能测试比较好的一些理念,交流性能测试中的经验与教训,明确每个组员下一个阶段需要完成的性能测试任务。
       XX在第XX季度得到较多的性能测试项目锻炼,进步明显。
      
    2 性能测试项目

             支持XX系统性能测试,挖掘包括数据转换错误、空指针错误以及内存泄露、连接池耗尽、操作系统inode节点满等多个深层次的异常。 同时给一些同事锻炼性能测试脚本锻炼的机会。

             与XX 一起做XX集群性能测试与容量规划性能测试,充分挖掘分布式计算特性,借用容量规划理论以及扩展loadrunner的 监控Linux能力。这也是XX系统做得最深的一次性能测试,也是容量规划的一个尝试。         

           支持XX等开展性能测试, review 大部份性能测试报告。      
          同时积极积累实战知识并文档化。
391/212>
Open Toolbar