发布新日志

  • 《测试之美》试评员

    2010-09-08 17:04:32

        参加了51Testing《测试之美》试评员招募,很幸运的成为了试评员,今天收到邮寄的《测试之美》,非常感谢51tesing,非常感谢51testing的编辑MM.书的封面是,一只小虫子(bug)爬行,留下一串串的脚印,第一眼看去,封面设计的不是很好,但是看的多了,忽然发现,其实也很美的。

        还没有看过书,无法评价,待我仔细研读,哈哈!

  • 用Jmeter做接口测试

    2010-08-29 10:02:40

        最近做接口测试,服务层的代码先是用junit写,因为项目时间紧,加上流程经常变化,单元测试代码写的很粗糙,需要不停的准备不同的测试数据,不能进行自动化的执行,一个方面是流程确实需要不同的测试数据,另外一个方面是,测试代码中没有对测试数据进行处理,所以会造成这样的情况,不过为了测试流程的正常性,这些进行测试也是可以的。

        在开发代码都稳定后,是用这样的测试方法肯定是不行的,也考虑过重构单元测试代码,但是因为项目调用到好几个服务,但是只有三个入口,而测试的主要目的是进行接口测试,单元测试只是辅助开发进行测试,所以如何进行更优化的接口测试是主要的。

        因为对Jmeter熟悉,再加上之前是用Jmeter做过HTTP协议的接口测试,所以考虑用jmeter来做接口测试,主要是使用Jmeter的java请求,编写相应的测试代码,在jmeter的代码中,调用入口方法,而方法需要的参数通过java请求的参数传递,这样可以使用参数化对传递的参数进行参数化,为了快速查找问题,在代码中,使用Jmeter提供的方法设置了请求的数据以及相应的数据,而为了验证测试结果是否通过,在代码中取得发放返回值,然后和期望值进行比较,如果一致,则测试结果为真,否则为测试失败。

        当然仅仅是在代码中对方法返回结果进行比较还不够,还需要到数据库去验证相应的数据是否存在,是否修改,这就用到了jmeter的beenshell断言,另外,因为测试结果也会在web页面中体现,所以也增加了http请求,设置断言,断言web页面的值和期望一致。

        通过以上方法,可以实现使用Jmeter进行接口测试,然后通过和ANT集成,每次在修改底层代码后,跑一遍测试脚本,基本上可以确认是否存在问题。

        另外使用jmeter准备的测试脚本,可以用来做性能测试,或者用来准备数据也是非常的方便!

        以上只是对流程进行描述,没有相应的代码,看的也学会云里雾里,后面会把代码贴上来!

  • selenium 使用junit4

    2010-08-20 15:46:35

    Selenium的开发提供的SeleneseTestCaseJunit3风格的,放在JUnit4底下跑,JUnit4Annotation功能就用不起来了。Selenium要启动浏览器,如果用不上@BeforeClass的话,每次启动都初始化一下Selenium,开个IE或者Firefox,这个测试的效率可吃不消(也有比较麻烦的Workaround,但总觉得不是很好)。而甩开SeleneseTestCase的话,又舍不得那个在测试没有通过的时候自动截屏的功能。网络上有人已经有解决方法,我整理如下:、

    编写MyRunListener,继承RunListener

    import org.junit.runner.notification.Failure;

    import org.junit.runner.notification.RunListener;

     

    public class MyRunListener extends RunListener {

        @Override

        public void testFailure(Failure failure) throws Exception {

          

        }

        }

    编写MyRunner

    import org.junit.runner.notification.RunNotifier;

    import org.junit.runners.BlockJUnit4ClassRunner;

    import org.junit.runners.model.InitializationError;

     

    public class MyRunner extends BlockJUnit4ClassRunner {

        private MyRunListener myRunListener;

     

           public MyRunner(Class<?> c) throws InitializationError {

              super(c);

              myRunListener = new MyRunListener();

           }

     

       @Override

        public void run(RunNotifier rn) {

               rn.addListener(myRunListener);

              super.run(rn);

     

        }

    }

    在测试代码中引入

    @RunWith(MyRunner.class)

    public class MyhomeTest extends SeleneseTestCase {

      具体的参与地址是: http://rockhoppertech.com/blogs/archives/45

  • selenium 对表格的验证

    2010-08-18 15:29:12

    通常页面上需要验证一个table里头的值对不对,这个table一般都没有id,所以可以用xpath来解决。

        第一步:识别该table 的某个cell。这里要注意通常一个table的第一行是表头,第二行才是具体的值,selenium识别行列从1开始数的,不是0.所以一个table的第1行第1列的值应该是:

    //table[@class='myTable']/tbody/tr[2]/td[1]

       第二步:加入验证点。

        首先要考虑这个table是不是存在,不存在就直接assertExist返回.

        然后考虑这个table是不是会返回很多行,如果需要验证每一个表格的内容,则用循环来控制:

      String table = "//div/table[@class='main-table']/tbody/tr";
      String tr = "//div/table[@class='main-table']/thead/tr/th";


      int rowNumber = selenium.getXpathCount(table).intValue();
      int lineNumber = selenium.getXpathCount(tr).intValue();


      for (int i = 1; i <= rowNumber; i++) {
        for (int j = 1; j <= lineNumber; j++) {
        String path = table + "[" + i + "]/td[" + j + "]";
        if (selenium.isElementPresent(path)) {
         String data = selenium.getText(path);
         assertNotNull(data);
        }
       }
      }

       第三步:如果是验证table的某列含有某个值:

      selenium.isElementPresent("//td[contains(text(),'my required text for verifying')]")

      也可以用:selenium.getText(path)得到那一列的值再判断:

        boolean exist = data.contains(myexpectData);
        assertEquals(exist, true);

  • 使用Beanshell Assertion实现Jmeter测试结果和数据库比对

    2010-08-12 20:03:02

        在使用jemeter的过程中,有时候希望能够将jmeter的响应结果直接和数据库进行比对,可以使用Beanshell Assertion实现Jmeter测试结果和数据库比对,参考如下


    import java.sql.*;
    import java.util.*;
    import java.lang.*;
    import org.apache.regexp.*;

    String drive = "com.mysql.jdbc.Driver";
    String url = "jdbc:mysql://19x.16x.xx.xx:3306/";
    String dbName = "Name";
    String user = "user";
    String pass = "pass";

    String Myvar = vars.get("Param");

    String query = "SELECT MyDescription From Mytable Where Mycriteria = '" + Myvar + "'";
    Connection Mycon = null;
    Statement Mystmt = null;
    ResultSet Myrset = null;

    String[] Comp = new String[24];
    RE rex;
    boolean found;

    String Mypattern;
    byte[ ] Myarr = (byte[ ])ResponseData;
    String Myresp = new String(Myarr);

    Mycon = DriverManager.getConnection(url+dbName, user, pass);
    Mystmt = Mycon.createStatement();
    Myrset = Mystmt.executeQuery(query);

    int a=1; int b=0;
    while (Myrset.next())
    {
    Comp[b] = Myrset.getString(1);
    print(" "+ (a) +" " + Comp[b]);

    Mypattern = Comp[b];
    rex = new RE(Mypattern);
    found = rex.match(Myresp);
    print(Mypattern + (found ? " DOES MATCH " : " DOESN'T MATCH ") + "Response Returned\n");

    if (found==false) 
    { Failure = true;
    FailureMessage = "The Values in the Response do not match the expected data."; }

    a=a+1; b=b+1;
    }

    Myrset.close();
    Mystmt.close();


        以上代码可以根据实际情况修改,可以实现数据库验证!
         
  • Jmeter培训计划

    2010-08-09 18:18:27

    一家国外网站的关于Jmeter的培训课程,看看有多少是自己不会的,可以研究研究!

    Introduction

    Why use JMeter?

    Overview of functional/regression/stress testing principles

    Designing a basic test plan

    How to identify your testing needs

    Defining the steps of your test

    Creating your first JMeter test

    Introducing the JMeter GUI

    The basic elements of a JMeter test plan

    Building a functional test with your Internet browser

    Executing your functional test

    Reading the results of your test

    The power of JMeter

    Comprehensive overview of the available JMeter components and functions

    Implementing an advanced functional test using the key JMeter functions and components

    Designing and implementing your own practical example to "test" a website of your choice

    Regression testing

    Using your functional tests for regression testing

    Future proofing your tests

    Stress testing

    Analysing your website traffic

    Identifying what you need to test

    Mimicking the real world in JMeter

    Extracting and reading the results

    Other key features

    Stress testing a database

    Using JMeter from the command line

    Editing a test plan in a text/XML editor

    Performance Testing Fundamentals

    Stress testing

    Load testing

    Soak testing

    Running multiple threads

    Setting rump-up period

    Threads and users

    Distributed Testing

    Configuring servers

    Gathering results

    Submitting Forms

    Extracting form. ID or checksums

    Generating sequence or random data

    Getting data from database

    Recording forms with a JMeter proxy server

    Submitting data recorded in log files

    Managing Sessions

    Session managers

    Session per thread

    Session per user

    Load Distribution

    Using Apache log files to determine distribution

    Analysing distribution and creating appropriate test plans

    Timers

    Gaussian Random Timer

    Other Resources and Load Time

    Images

    Java scripts

    JMeter and HTTP headers policy (browser and proxy caching)

    Resource Monitoring

    Monitoring and analysing CPU resources

    Monitoring database queries

    Monitoring memory utilization

    Monitoring network traffic

    Running monitoring tools periodically

    Analysing and Interpreting Load Test Results

    Running tests at night and creating periodical reports

    Statistics available from JMeter

    Sample, Average, Median, Deviation, Throughput

    Response time graphs

    Margins of Error

    Analysing results with Excel

    Interpreting statistical results

    Finding the bottlenecks

    Regression and correlations

    Distributed (Remote) Testing

    Preparing remote environment

    Running distributed

    Gethering and analysing results

    Using distributed testing with load balancers

    Variables

    Creating user variable

    Extracting data from a web page to a variable

    Functions

    Using functions

    Function helper

    Using BeanShell Scripting

    Short introduction to BeanShell

    Creating samplers

    BeanShell listener

    __BeanShell function

    Testing Application with Real Data

    Configuring Apache Web Server to record appropriate data

    Access Log Sampler

    Security issues

     

  • Eclipse下编译jmeter2.4源代码

    2010-07-31 00:28:26

    1,下载jakarta-jmeter-2.4_src.zip和jakarta-jmeter-2.4.zip解压。


    2,下载3个jar包,(很重要要不会有n多的错误),分别是mail.jar,jms.jar,activation.jar


    3,将jakarta-jmeter-2.4.zip下的lib中的jar包拷到jakarta-jmeter-2.4_src.zip下的lib目录中并加上下载的三个jar包。并且修改commons-logging1.1.jar为commons-logging.jar。然后在lib目录下新增三个空文件夹ext,junit,api.(主要是为了对应Jmeter的eclipse.classpath。)
    4,打开eclipse,新建java工程,命名,选择import,选择从文件导入,选择jakarta-jmeter-2.4_src.zip解压后的目录,选择除src目录以外的所有目录。之后再导入src目录(因为新建java工程是已经有src目录了),所以要分别导入。
    6,关闭eclipse将jakarta-jmeter-2.4_src.zip下的eclipse.classpath中的内容复制一份替换工程下的.classpath的内容,然后重新开启eclipse,选择工程编译,这个时候,会有一些编译的错误,主要是jar包不存在或者jar包的版本名称不一致,下载相应的jar包或者修改jar包名称,使之符合.classpath描述信息,直至编译不报错。

    7,jmeter源代码org.apache.jmeter.assertions.SMIMEAssertion会报错,主要是缺少org.bouncycastle对应的包,下载该包。

    8,此时可正常编译,编译通过后,使用ANT正常编译(需要本机安装ANT,并且需要设置jdl环境变量)

    9,ant编译通过后,选择org.apache.jmeter.NewDriver设置运行配置,在Arguments" 标签中,工作目录不选择默认,而选择其他设置/{工程目录}/bin,其他默认。或者可以参考http://people.apache.org/~mkostrze/jmeter-eclipse/index.html 

    10.设置成功后,就可以运行或者debugJmeter。


     

  • JMeter 2.4发布

    2010-07-30 21:11:40

    JMeter 2.4主要改进包括:
    1.升级了对Java版本的要求,目前需要最低Java 1.5的支持。
    2.改进了HTTP代理功能,支持记录HTTPS session的功能。
    3.升级了JUnit对现在JUnit4的支持注解
    4.增加了JSR223(javax.script)测试元素的内容
    5.改进了MailReader类以支持多种协议
    6.增加了SMTP 的示例代码
    7.支持用户自定义线程组功能的实现
    8.增加了树形结果展示的选项,包括检索功能和正则表达式测试。
    9.提高了StatCalculator,聚合报表的性能,运行时这些功能的需要的内存变得更小
  • Jmeter问题记录

    2010-07-06 18:27:01

        论坛的Jmeter板块中有好多朋友问一些问题,对于一些可以使用文字回答,并且自己能够回答的问题,记录在此:

    1. Mysql数据库的压力测试聚合报告里给出 Error% 为62% 设置了150个线程 报错62%信息提示是 超时

    答:这个原因是因为连接超时,因为jmeter的JDBC Connection Configuration 默认设置的 Max Number of Connections是10,Pool TimeOUT是10000ms,你可以增大Max Number of Connections,或者增大Pool TimeOUT。

    2. JMeter读取CSV中中文都是乱码,HTTP请求中,发送参数,如果是中文最后显示乱码。

    答:同请求一起发生的参数中,编码字段是否勾选,如果没有勾选,勾选,看是否可以纠正。

  • Jmeter测试ORACLE数据库并发---索引的优点

    2010-07-03 17:00:19

    1,测试验证用到的简单的sql语句:
    /* Formatted on 2010-6-29 11:56:58 (QP5 v5.115.810.9015) */
    SELECT   *
      FROM   (SELECT   row_.*, ROWNUM rownum_
                FROM   (SELECT   "order_date"
                          FROM   "test"
                         WHERE   "order_no" =
                                    TRUNC (DBMS_RANDOM.VALUE (24, 50024))) row_
               WHERE   ROWNUM <= 20)
    WHERE   rownum_ > 0

    2,数据准备说明
    a,本次对一个有5个字段的表test进行基本测试,验证两种情况:一,字段order_no有索引;二,字段order_no无所有,有无索引时做相同的测试验证
       b,相应时间单位:ms
       c,测试验证分同时并发和分钟并发两种情况验证
       d,表中有50000条数据
    3,测试得到的数据

    同时并发(Ramp-Up Period=0)---单位ms
    10并发 50并发 80并发 100并发
    无索引 756 2109 3053 3723
    有索引 357 385 413 430


    分钟并发(Ramp-Up Period=60)---单位ms
    200并发 500并发 1000并发 1500并发
    无索引 255 260 10702 33163
    有索引 4 3 1 4


    4,结论总结
    1,500以下的并发,有无索引,用户不会有太明显的感觉,因为他们的执行时间都不会大于0.3s
    2,以“较高(500~3000)”并发频率对50000数据的表进行简单的查询,此时有无索引就会有明显的差别,可以达到5s以上
    3,以“极高(>3000)”并发频率对50000数据的表进行简单的查询,此时相应时间就会很慢,很慢

        结合实际应用考虑,一些简单的表(字段不太多,结果不复杂),在单个用户反复执行sql语句时,有无索引对用户来说可能体验不到响应时间上的差异,而对于多用户并发对这个表做操作时,有无索引的差异就会很明显:在“较低”频率并发情况下,由于表比较简单,响应时间很小,看不出大的差异,当并发频率“较高”,如大于500时,这种差异就会很明显,如上面1500的并发,响应时间相差3s,依此类推,如果表字段很多,嵌套结构复杂,有无索引并发执行的差异将会很大。
  • Jmeter测试结果文件的分析

    2010-05-08 12:30:57

      在性能测试过程中,我们往往需要将测试结果保存在一个文件当中,这样既可以保存测试结果,也可以为日后的性能测试报告提供更多的素材。

      Jmeter中,结果都存放在.jtl文件。这个.jtl文件可以提供多种格式的编写,而一般我们都是将其以csv文件格式记录,这样做是因为csv文件格式看起来比较方便,更重要的是这样做可以为二次分析提供很多便利。

      我这里所说的二次分析是指除了使用Listener之外,我们还可以对.jtl文件进行再次分析。

      a.设置jtl文件格式

      我们从jmeter官方网站中下载下来的Jmeter解压后是可以直接使用的。但是,使用默认配置生成的jtl文件内容并不能满足我们的需要。于是我们必须进行必要的设置。在2.2版本中,如果要修改jtl设置必须要到jmeter.properties文件中设置;但是在2.3版本中,我们只需要在界面上设置就可以了。你只需要选择某个Listener,点击页面中的configure按钮。此时,一个设置界面就会弹出来,建议多勾选如下项:Save Field Name,Save Assertion Failure Message。

      b.jtl文件中的各项

      经过了以上设置,此时保存下来的jtl文件会有如下项:

      timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,Latency

      请求发出的绝对时间,响应时间,请求的标签,返回码,返回消息,请求所属的线程,数据类型,是否成功,失败信息,字节,响应时间

      其中聚合报告中的,吞吐量=完成的transaction数/完成这些transaction数所需要的时间;平均响应时间=所有响应时间的总和/完成的transaction数;失败率=失败的个数/transaction数

      温馨提示:在jmeter2.2和2.3版本中,都存在的一个问题是当我们重新打开jmeter,使用某个Listener来查看jtl文件时,jmeter是会报错的。因此当你使用命令行方式完成了一个场景的测试后,你得到的只是一堆保存在jtl文件中的原始数据。所以知道聚合报告中的各项的来源是可以方便大家摆脱测试工具来进行结果的分析。 

      总的来说,对于jmeter的结果分析,主要就是对jtl文件中原始数据的整理,我是使用一些小脚本进行相关的分析的,不知道你打算怎么做呢?

      反正实践后,你总能找到一条属于自己的数据分析之路。

  • HTTP协议详解(收藏)

    2010-05-08 12:18:36

    引言                                       
     
    HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的
    使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-
    NG(Next Generation of HTTP)的建议已经提出。
    HTTP协议的主要特点可概括如下:
    1.支持客户/服务器模式。
    2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服
    务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
    3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
    4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方
    式可以节省传输时间。
    5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则
    它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

    一、HTTP协议详解之URL篇

        http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方
    式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。

    HTTP URL (URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息)的格式如下:
    http://host[":"port][abs_path]
    http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,
    为空则使用缺省端口80;abs_path指定请求资源的URI;如果URL中没有给出abs_path,那么当它作为请求URI
    时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。
    eg:
    1、输入:
    www.guet.edu.cn
    浏览器自动转换成:http://www.guet.edu.cn/
    2、http:192.168.0.116:8080/index.jsp 

    二、HTTP协议详解之请求篇

        http请求由三部分组成,分别是:请求行、消息报头、请求正文

    1、请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Method Request-
    URI HTTP-Version CRLF 
    其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;
    CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。

    请求方法(所有方法全为大写)有多种,各个方法的解释如下:
    GET     请求获取Request-URI所标识的资源
    POST    在Request-URI所标识的资源后附加新的数据
    HEAD    请求获取由Request-URI所标识的资源的响应消息报头
    PUT     请求服务器存储一个资源,并用Request-URI作为其标识
    DELETE  请求服务器删除Request-URI所标识的资源
    TRACE   请求服务器回送收到的请求信息,主要用于测试或诊断
    CONNECT 保留将来使用
    OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
    应用举例:
    GET方法:在浏览器的地址栏中输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源,
    eg:GET /form.html HTTP/1.1 (CRLF)

    POST方法要求被请求服务器接受附在请求后面的数据,常用于提交表单。
    eg:POST /reg.jsp HTTP/ (CRLF)
    Accept:image/gif,image/x-xbit,... (CRLF)
    ...
    HOST:www.guet.edu.cn (CRLF)
    Content-Length:22 (CRLF)
    Connection:Keep-Alive (CRLF)
    Cache-Control:no-cache (CRLF)
    (CRLF)         //该CRLF表示消息报头已经结束,在此之前为消息报头
    user=jeffrey&pwd=1234  //此行以下为提交的数据

    HEAD方法与GET方法几乎是一样的,对于HEAD请求的回应部分来说,它的HTTP头部中包含的信息与通过
    GET请求所得到的信息是相同的。利用这个方法,不必传输整个资源内容,就可以得到Request-URI所标识的资
    源的信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。
    2、请求报头后述
    3、请求正文(略) 

    三、HTTP协议详解之响应篇

        在接收和解释请求消息后,服务器返回一个HTTP响应消息。

    HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
    1、状态行格式如下:
    HTTP-Version Status-Code Reason-Phrase CRLF
    其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase
    表示状态代码的文本描述。
    状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
    1xx:指示信息--表示请求已接收,继续处理
    2xx:成功--表示请求已被成功接收、理解、接受
    3xx:重定向--要完成请求必须进行更进一步的操作
    4xx:客户端错误--请求有语法错误或请求无法实现
    5xx:服务器端错误--服务器未能实现合法的请求
    常见状态代码、状态描述、说明:
    200 OK      //客户端请求成功
    400 Bad Request  //客户端请求有语法错误,不能被服务器所理解
    401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报                 //头域一起使用
    403 Forbidden  //服务器收到请求,但是拒绝提供服务
    404 Not Found  //请求资源不存在,eg:输入了错误的URL
    500 Internal Server Error //服务器发生不可预期的错误
    503 Server Unavailable  //服务器当前不能处理客户端的请求,一段时间后,                         //可能恢复正常
    eg:HTTP/1.1 200 OK (CRLF)

    2、响应报头后述

    3、响应正文就是服务器返回的资源的内容 

    四、HTTP协议详解之消息报头篇

        HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对
    于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有
    CRLF的行),消息正文(可选)组成。

    HTTP消息报头包括普通报头、请求报头、响应报头、实体报头。
    每一个报头域都是由名字+“:”+空格+值 组成,消息报头域的名字是大小写无关的。

    1、普通报头
    在普通报头中,有少数报头域用于所有的请求和响应消息,但并不用于被传输的实体,只用于传输的消息。
    eg:
    Cache-Control   用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是
    独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制),HTTP1.0使用的类似的报头域为Pragma。
    请求时的缓存指令包括:no-cache(用于指示请求或响应消息不能缓存)、no-store、max-age、max-stale、min-
    fresh、only-if-cached;
    响应时的缓存指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、
    max-age、s-maxage.
    eg:为了指示IE浏览器(客户端)不要缓存页面,服务器端的JSP程序可以编写如下:response.sehHeader
    ("Cache-Control","no-cache");
    //response.setHeader("Pragma","no-cache");作用相当于上述代码,通常两者//合用
    这句代码将在发送的响应消息中设置普通报头域:Cache-Control:no-cache


    Date普通报头域表示消息产生的日期和时间

    Connection普通报头域允许发送指定连接的选项。例如指定连接是连续,或者指定“close”选项,通知服务
    器,在响应完成后,关闭连接

    2、请求报头
    请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。
    常用的请求报头
    Accept
    Accept请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:image/gif,表明客户端希望接受GIF图象
    格式的资源;Accept:text/html,表明客户端希望接受html文本。
    Accept-Charset
    Accept-Charset请求报头域用于指定客户端接受的字符集。eg:Accept-Charset:iso-8859-1,gb2312.如果在请求消
    息中没有设置这个域,缺省是任何字符集都可以接受。
    Accept-Encoding
    Accept-Encoding请求报头域类似于Accept,但是它是用于指定可接受的内容编码。eg:Accept-Encoding:gzip.deflate.如果请求消息中没有设置这个域服务器假定客户端对各种内容编码都可以接受。
    Accept-Language
    Accept-Language请求报头域类似于Accept,但是它是用于指定一种自然语言。eg:Accept-Language:zh-cn.如果请
    求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。
    Authorization
    Authorization请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器
    的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。
    Host(发送请求时,该报头域是必需的)
    Host请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的,eg:
    我们在浏览器中输入:
    http://www.guet.edu.cn/index.html
    浏览器发送的请求消息中,就会包含Host请求报头域,如下:
    Host:
    www.guet.edu.cn
    此处使用缺省端口号80,若指定了端口号,则变成:Host:www.guet.edu.cn:指定端口号
    User-Agent
    我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的
    浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头
    域中获取到这些信息。User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。不
    过,这个报头域不是必需的,如果我们自己编写一个浏览器,不使用User-Agent请求报头域,那么服务器端就
    无法得知我们的信息了。
    请求报头举例:
    GET /form.html HTTP/1.1 (CRLF)
    Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-
    powerpoint,application/msword,*/* (CRLF)
    Accept-Language:zh-cn (CRLF)
    Accept-Encoding:gzip,deflate (CRLF)
    If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)
    If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)
    User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)
    Host:www.guet.edu.cn (CRLF)
    Connection:Keep-Alive (CRLF)
    (CRLF)

    3、响应报头
    响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和对Request-URI所标识
    的资源进行下一步访问的信息。
    常用的响应报头
    Location
    Location响应报头域用于重定向接受者到一个新的位置。Location响应报头域常用在更换域名的时候。
    Server
    Server响应报头域包含了服务器用来处理请求的软件信息。与User-Agent请求报头域是相对应的。下面是
    Server响应报头域的一个例子:
    Server:Apache-Coyote/1.1
    WWW-Authenticate
    WWW-Authenticate响应报头域必须被包含在401(未授权的)响应消息中,客户端收到401响应消息时候,并发
    送Authorization报头域请求服务器对其进行验证时,服务端响应报头就包含该报头域。
    eg:WWW-Authenticate:Basic realm="Basic Auth Test!"  //可以看出服务器对请求资源采用的是基本验证机制。


    4、实体报头
    请求和响应消息都可以传送一个实体。一个实体由实体报头域和实体正文组成,但并不是说实体报头域和实体正文要在一起发送,可以只发送实体报头域。实体报头定义了关于实体正文(eg:有无实体正文)和请求所标识的资源的元信息。
    常用的实体报头
    Content-Encoding
    Content-Encoding实体报头域被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编
    码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding这样用
    于记录文档的压缩方法,eg:Content-Encoding:gzip
    Content-Language
    Content-Language实体报头域描述了资源所用的自然语言。没有设置该域则认为实体内容将提供给所有的语言
    阅读
    者。eg:Content-Language:da
    Content-Length
    Content-Length实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示。
    Content-Type
    Content-Type实体报头域用语指明发送给接收者的实体正文的媒体类型。eg:
    Content-Type:text/html;charset=ISO-8859-1
    Content-Type:text/html;charset=GB2312
    Last-Modified
    Last-Modified实体报头域用于指示资源的最后修改日期和时间。
    Expires
    Expires实体报头域给出响应过期的日期和时间。为了让代理服务器或浏览器在一段时间以后更新缓存中(再次
    访问曾访问过的页面时,直接从缓存中加载,缩短响应时间和降低服务器负载)的页面,我们可以使用Expires
    实体报头域指定页面过期的时间。eg:Expires:Thu,15 Sep 2006 16:23:12 GMT
    HTTP1.1的客户端和缓存必须将其他非法的日期格式(包括0)看作已经过期。eg:为了让浏览器不要缓存页
    面,我们也可以利用Expires实体报头域,设置为0,jsp中程序如下:response.setDateHeader("Expires","0");

    五、利用telnet观察http协议的通讯过程

        实验目的及原理:
        利用MS的telnet工具,通过手动输入http请求信息的方式,向服务器发出请求,服务器接收、解释和接受请求
    后,会返回一个响应,该响应会在telnet窗口上显示出来,从而从感性上加深对http协议的通讯过程的认识。

        实验步骤:

    1、打开telnet
    1.1 打开telnet
    运行-->cmd-->telnet

    1.2 打开telnet回显功能
    set localecho

    2、连接服务器并发送请求
    2.1 open
    www.guet.edu.cn 80  //注意端口号不能省略

        HEAD /index.asp HTTP/1.0
        Host:www.guet.edu.cn
       
       /*我们可以变换请求方法,请求桂林电子主页内容,输入消息如下*/
        open
    www.guet.edu.cn 80
      
        GET /index.asp HTTP/1.0  //请求资源的内容
        Host:www.guet.edu.cn  

    2.2 open www.sina.com.cn 80  //在命令提示符号下直接输入telnet www.sina.com.cn 80
        HEAD /index.asp HTTP/1.0
        Host:www.sina.com.cn
     

    3 实验结果:

    3.1 请求信息2.1得到的响应是:

    HTTP/1.1 200 OK                                              //请求成功
    Server: Microsoft-IIS/5.0                                    //web服务器
    Date: Thu,08 Mar 200707:17:51 GMT
    Connection: Keep-Alive                                
    Content-Length: 23330
    Content-Type: text/html
    Expries: Thu,08 Mar 2007 07:16:51 GMT
    Set-Cookie: ASPSESSIONIDQAQBQQQB=BEJCDGKADEDJKLKKAJEOIMMH; path=/
    Cache-control: private

    //资源内容省略

    3.2 请求信息2.2得到的响应是:

    HTTP/1.0 404 Not Found       //请求失败
    Date: Thu, 08 Mar 2007 07:50:50 GMT
    Server: Apache/2.0.54 <Unix>
    Last-Modified: Thu, 30 Nov 2006 11:35:41 GMT
    ETag: "6277a-415-e7c76980"
    Accept-Ranges: bytes
    X-Powered-By: mod_xlayout_jh/0.0.1vhs.markII.remix
    Vary: Accept-Encoding
    Content-Type: text/html
    X-Cache: MISS from zjm152-78.sina.com.cn
    Via: 1.0 zjm152-78.sina.com.cn:80<squid/2.6.STABLES-20061207>
    X-Cache: MISS from th-143.sina.com.cn
    Connection: close


    失去了跟主机的连接

    按任意键继续...


    4 .注意事项:1、出现输入错误,则请求不会成功。
              2、报头域不分大小写。
              3、更深一步了解HTTP协议,可以查看RFC2616,在
    http://www.letf.org/rfc上找到该文件。
              4、开发后台程序必须掌握http协议

     

    六、HTTP协议相关技术补充

        1、基础:
        高层协议有:文件传输协议FTP、电子邮件传输协议SMTP、域名系统服务DNS、网络新闻传输协议NNTP和
    HTTP协议等
    中介由三种:代理(Proxy)、网关(Gateway)和通道(Tunnel),一个代理根据URI的绝对格式来接受请求,重写全部
    或部分消息,通过 URI的标识把已格式化过的请求发送到服务器。网关是一个接收代理,作为一些其它服务
    器的上层,并且如果必须的话,可以把请求翻译给下层的服务器协议。一 个通道作为不改变消息的两个连接
    之间的中继点。当通讯需要通过一个中介(例如:防火墙等)或者是中介不能识别消息的内容时,通道经常被使
    用。
         代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。
    请求是通过可能的翻译在内部或经过传递到其它的 服务器中。一个代理在发送请求信息之前,必须解释并且
    如果可能重写它。代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处
    理没有被用户代理完成的请求。
    网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的
    资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
      网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非
    HTTP系统中的资源。
        通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能
    是被一个HTTP请求初始化的。当被中继 的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介
    (Intermediary)不能解释中继的通讯时通道被经常使用。


    2、协议分析的优势—HTTP分析器检测网络攻击
    以模块化的方式对高层协议进行分析处理,将是未来入侵检测的方向。
    HTTP及其代理的常用端口80、3128和8080在network部分用port标签进行了规定

    3、HTTP协议Content Lenth限制漏洞导致拒绝服务攻击
    使用POST方法时,可以设置ContentLenth来定义需要传送的数据长度,例如ContentLenth:999999999,在传送完
    成前,内 存不会释放,攻击者可以利用这个缺陷,连续向WEB服务器发送垃圾数据直至WEB服务器内存耗
    尽。这种攻击方法基本不会留下痕迹。
    http://www.cnpaf.net/Class/HTTP/0532918532667330.html


    4、利用HTTP协议的特性进行拒绝服务攻击的一些构思
    服务器端忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之
    小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYNFlood攻击(SYN洪水攻击)。
    而Smurf、TearDrop等是利用ICMP报文来Flood和IP碎片攻击的。本文用“正常连接”的方法来产生拒绝服务攻击。
    19端口在早期已经有人用来做Chargen攻击了,即Chargen_Denial_of_Service,但是!他们用的方法是在两台
    Chargen 服务器之间产生UDP连接,让服务器处理过多信息而DOWN掉,那么,干掉一台WEB服务器的条件就
    必须有2个:1.有Chargen服务2.有HTTP 服务
    方法:攻击者伪造源IP给N台Chargen发送连接请求(Connect),Chargen接收到连接后就会返回每秒72字节的
    字符流(实际上根据网络实际情况,这个速度更快)给服务器。


    5、Http指纹识别技术
       Http指纹识别的原理大致上也是相同的:记录不同服务器对Http协议执行中的微小差别进行识别.Http指纹识
    别比TCP/IP堆栈指纹识别复杂许 多,理由是定制Http服务器的配置文件、增加插件或组件使得更改Http的响应
    信息变的很容易,这样使得识别变的困难;然而定制TCP/IP堆栈的行为 需要对核心层进行修改,所以就容易识
    别.
          要让服务器返回不同的Banner信息的设置是很简单的,象Apache这样的开放源代码的Http服务器,用户可以在
    源代码里修改Banner信息,然 后重起Http服务就生效了;对于没有公开源代码的Http服务器比如微软的IIS或者
    是Netscape,可以在存放Banner信息的Dll文件中修 改,相关的文章有讨论的,这里不再赘述,当然这样的修改的效果
    还是不错的.另外一种模糊Banner信息的方法是使用插件。
    常用测试请求:
    1:HEAD/Http/1.0发送基本的Http请求
    2:DELETE/Http/1.0发送那些不被允许的请求,比如Delete请求
    3:GET/Http/3.0发送一个非法版本的Http协议请求
    4:GET/JUNK/1.0发送一个不正确规格的Http协议请求
    Http指纹识别工具Httprint,它通过运用统计学原理,组合模糊的逻辑学技术,能很有效的确定Http服务器的类型.它
    可以被用来收集和分析不同Http服务器产生的签名。


    6、其他:为了提高用户使用浏览器时的性能,现代浏览器还支持并发的访问方式,浏览一个网页时同时建立
    多个连接,以迅速获得一个网页上的多个图标,这样能更快速完成整个网页的传输。
    HTTP1.1中提供了这种持续连接的方式,而下一代HTTP协议:HTTP-NG更增加了有关会话控制、丰富的内容
    协商等方式的支持,来提供
    更高效率的连接。

  • 精妙 SQL 语句收集

    2010-05-01 00:04:45

    转载此文,以备后用

     

    原文转至CSDN http://blog.csdn.net/chen8148/archive/2007/08/14/1741991.aspx

     

    SQL语句先前写的时候,很容易把一些特殊的用法忘记,我特此整理了一下SQL语句操作。

    一、基础

    1、说明:创建数据库

    CREATE DATABASE database-name

    2、说明:删除数据库

    drop database dbname

    3、说明:备份sql server

    --- 创建 备份数据的 device

    USE master

    EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'

    --- 开始 备份

    BACKUP DATABASE pubs TO testBack

    4、说明:创建新表

    create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)

    根据已有的表创建新表:

    Acreate table tab_new like tab_old (使用旧表创建新表)

    Bcreate table tab_new as select col1,col2... from tab_old definition only

    5、说明:删除新表

    drop table tabname

    6、说明:增加一个列

    Alter table tabname add column col type

    注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。

    7、说明:添加主键: Alter table tabname add primary key(col)

    说明:删除主键: Alter table tabname drop primary key(col)

    8、说明:创建索引:create [unique] index idxname on tabname(col....)

    删除索引:drop index idxname

    注:索引是不可更改的,想更改必须删除重新建。

    9、说明:创建视图:create view viewname as select statement

    删除视图:drop view viewname

    10、说明:几个简单的基本的sql语句

    选择:select * from table1 where 范围

    插入:insert into table1(field1,field2) values(value1,value2)

    删除:delete from table1 where 范围

    更新:update table1 set field1=value1 where 范围

    查找:select * from table1 where field1 like '%value1%' ---like的语法很精妙,查资料!

    排序:select * from table1 order by field1,field2 [desc]

    总数:select count as totalcount from table1

    求和:select sum(field1) as sumvalue from table1

    平均:select avg(field1) as avgvalue from table1

    最大:select max(field1) as maxvalue from table1

    最小:select min(field1) as minvalue from table1

    11、说明:几个高级查询运算词

    A UNION 运算符

    UNION 运算符通过组合其他两个结果表(例如 TABLE1 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2

    B EXCEPT 运算符

    EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。

    C INTERSECT 运算符

    INTERSECT 运算符通过只包括 TABLE1 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。

    注:使用运算词的几个查询结果行必须是一致的。

    12、说明:使用外连接

    Aleft outer join

    左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。

    SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

    Bright outer join:

    右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。

    Cfull outer join

    全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。

    二、提升

    1、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)

    法一:select * into b from a where 1<>1

    法二:select top 0 * into b from a

    2、说明:拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)

    insert into b(a, b, c) select d,e,f from b;

    3、说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)

    insert into b(a, b, c) select d,e,f from b in '具体数据库' where 条件

    例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..

    4、说明:子查询(表名1a 表名2b)

    select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)

    5、说明:显示文章、提交人和最后回复时间

    select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

    6、说明:外连接查询(表名1a 表名2b)

    select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

    7、说明:在线视图查询(表名1a )

    select * from (SELECT a,b,c FROM a) T where t.a > 1;

    8、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括

    select * from table1 where time between time1 and time2

    select a,b,c, from table1 where a not between 数值1 and 数值2

    9、说明:in 的使用方法

    select * from table1 where a [not] in ('1','2','4','6')

    10、说明:两张关联表,删除主表中已经在副表中没有的信息

    delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )

    11、说明:四表联查问题:

    select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

    12、说明:日程安排提前五分钟提醒

    SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5

    13、说明:一条sql 语句搞定数据库分页

    select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段

    14、说明:前10条记录

    select top 10 * form. table1 where 范围

    15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)

    select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

    16、说明:包括所有在 TableA 中但不在 TableBTableC 中的行并消除所有重复行而派生出一个结果表

    (select a from tableA ) except (select a from tableB) except (select a from tableC)

    17、说明:随机取出10条数据

    select top 10 * from tablename order by newid()

    18、说明:随机选择记录

    select newid()

    19、说明:删除重复记录

    Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

    20、说明:列出数据库里所有的表名

    select name from sysobjects where type='U'

    21、说明:列出表里的所有的

    select name from syscolumns where id=object_id('TableName')

    22、说明:列示typevenderpcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case

    select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type

    显示结果:

    type vender pcs

    电脑 A 1

    电脑 A 1

    光盘 B 2

    光盘 A 2

    手机 B 3

    手机 C 3

    23、说明:初始化表table1

    TRUNCATE TABLE table1

    24、说明:选择从1015的记录

    select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc

    三、技巧

    11=11=2的使用,在SQL语句组合时用的较多

    "where 1=1" 是表示选择全部   "where 1=2"全部不选,

    如:

    if @strWhere !=''

    begin

    set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere

    end

    else

    begin

    set @strSQL = 'select count(*) as Total from [' + @tblName + ']'

    end

    我们可以直接写成

    set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere

    2、收缩数据库

    --重建索引

    DBCC REINDEX

    DBCC INDEXDEFRAG

    --收缩数据和日志

    DBCC SHRINKDB

    DBCC SHRINKFILE

    3、压缩数据库

    dbcc shrinkdatabase(dbname)

    4、转移数据库给新用户以已存在用户权限

    exec sp_change_users_login 'update_one','newname','oldname'

    go

    5、检查备份集

    RESTORE VERIFYONLY from disk='E:\dvbbs.bak'

    6、修复数据库

    ALTER DATABASE [dvbbs] SET SINGLE_USER

    GO

    DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK

    GO

    ALTER DATABASE [dvbbs] SET MULTI_USER

    GO

    7、日志清除

    SET NOCOUNT ON

    DECLARE @LogicalFileName sysname,

            @MaxMinutes INT,

            @NewSize INT

     

  • Jmete中的Java Reuest的使用方式

    2010-01-24 16:53:58

        使用Jmete中的Java Reuest,可以对编写的java类或者方法进行测试,Jmeter没有自带编译器,需要借助第三方编译器才能实现,因此使用Java编译器编写测试代码,将测试代码和需要测试的类都放入Jmeterlib文件夹下,然后再Jmeter中添加Java Reuest,就可以进行相应的测试了,下面结合一个实际的例子说明了如何使用Java Reuest

     

    1.     打开Java编译器,新建一个项目"JavaRequest",然后新建一个包"Jmeter.JavaRequest".

    2.        "JavaRequest"项目中,引入ApacheJMeter_core.jar""ApacheJMeter_java.jar这两个JAR文件.(具体的引入方法参考各个Java编译器的使用方法)

    3.         "Jmeter.JavaRequest"包中新建一个类,名字叫"TestJmeterRequest",这个类要继承"AbstractJavaSamplerClient",如果项目引入步骤二中的两个文件,就可以找到"AbstractJavaSamplerClient"类了.

    4.       "TestJmeterRequest"类在继承"AbstractJavaSamplerClient"类的同时也会继承四个方法,分别是"getDefaultParameters","setupTest","runTest""teardownTest"方法."getDefaultParameters"方法主要用于设置传入的参数;"setupTest"方法为初始化方法,用于初始化性能测试时的每个线程."runTest"方法为性能测试时的线程运行体;"teardownTest"方法为测试结束方法,用于结束性能测试中的每个线程.

    5.       具体实现代码如下:

    package Jmeter.JavaRequest;

     

    import org.apache.jmeter.config.Arguments;

    import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;

    import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;

    import org.apache.jmeter.samplers.SampleResult;

     

    public class DataBase extends AbstractJavaSamplerClient {

      private static String label = "databaseTest";

      private String sql1;

      private String sql2;

        private SampleResult results;

        private String testStr;

       

      public void setupTest(JavaSamplerContext arg0)

      {

            System.out.println("setupTest");

            results = new SampleResult();

            testStr = arg0.getParameter("testString", "");

            if (testStr != null && testStr.length() > 0) {

                   results.setSamplerData(testStr);

            }

      }

     

      public SampleResult runTest(JavaSamplerContext arg0)

     

      {

            sql1 = arg0.getParameter("host");

     

            sql2 = arg0.getParameter("port");

     

            SampleResult sr;

     

            sr = new SampleResult();

     

            sr.setSampleLabel(label);

     

            try

     

            { // 这里调用我们要测试的java类,这里我调用的是一个DatabaseTest

     

                 DatabaseTest datatest=new DatabaseTest();;

                 //datatest.main(null);// 调用要测试的方法

                 datatest.initialConnection();

     

                 sr.sampleStart(); // 记录程序执行时间,以及执行结果

     

                 sr.setSuccessful(true);

     

                 System.out.println("send over!");

     

            } catch (Throwable e)

     

            {

                 System.out.println("Exception is " + e.getMessage());

     

                 sr.setSuccessful(false);

     

            } finally

     

            {

                 sr.sampleEnd();

            }

     

            return sr;

      }

     

      public void teardownTest(JavaSamplerContext arg0)

     

      {

      }

     

      public Arguments getDefaultParameters()

     

      {

            Arguments params = new Arguments();

             params.addArgument("sql1", "");

             params.addArgument("sql2", "");

            return params;

     

      }

     

    }

    6.     把上面的例子打包,然后把生成的"TestJavaRequest.jar"文件拷贝到Jmeter的安装目录lib\ext.

    7.       运行Jmeter,添加一个线程组,然后在该线程组下面添加一个Java请求(Sampler),Java请求的类名称中选择刚创建的类"Jmeter.JavaRequest. TestJavaRequest ",然后添加一个监听器(聚合报告),设置一下模拟的用户数就可以测试了.如果测试不成功,Jmeter会在它自己个输出框中抛出这个字符串.
          
    使用Jmeter自定义Java测试代码,配合Jmeter自带的函数,就可以实现出LoadRunner"Java Vuser"协议的绝大多数功能.

  • LoadRunner监控服务器

    2009-04-21 11:37:19

    ************************本文非原创 **************转贴 51testing********************

    一、监控windows系统:
    1、监视连接前的准备工作
            1)进入被监视windows系统,开启以下二个服务Remote Procedure Call(RPC) 和Remote Registry Service (开始—)运行中输入services.msc,开启对应服务即可)。
            2)在被监视的WINDOWS机器上:右击我的电脑,选择管理->共享文件夹->共享在这里面要有C$这个共享文件夹 (要是没有自己手动加上)。
            3)在安装LR的机器上,开始—》运行,输入 \\被监视机器IP\C$ 然后输入管理员帐号和密码,如果能看到被监视机器的C盘了,就说明你得到了那台机器的管理员权限,可以使用LR去连接了。(LR要连接WINDOWS机器进行监视要有管理员帐号和密码才行。)
        问题:在执行步骤3)时,输入 \\被监视机器IP\C$,出现不能以administrator身份访问被监控系统(若采用这种方式用LR对其监控的话,会提示:“找不到网络路径”)的情况,现象就是用户名输入框是灰色的,并且默认用户是guest。
        解决办法:这是安全策略的设置问题(管理工具 -> 本地安全策略 -> 安全选项 -> "网络访问:本地帐户的共享和安全模式")。默认情况下,XP的访问方式是"仅来宾"的方式,如果你访问它,当然就固定为Guest来访问,而guest账户没有监控的权限,所以要把访问方式改为“经典”模式,这样就可以以administrator的身份登陆了。修改后,再次执行步骤3),输入管理员用户名和密码,就可以访问被监控机器C盘了
        若这样都不行的话(可能是其它问题引起的),那只好采取别的方法了。在服务器的机子上,通过windows自带的“性能日志和警报”下的“计数器日志”中新增加一个监控日志(管理工具—)性能—)性能日志和警报),配置好日志,也能监控服务器的cpu、memory、disk等计数器。当然,这种方法就不是用LR来监控了。

    2、用LR监视windows的步骤
        在controller 中,Windows Resources窗口中右击鼠标选择Add Measurements,添加被监控windows的IP地址,选择所属系统,然后选择需要监控的指标就可以开始监控了。

    二、监控linux
    1 准备工作
       可以通过两种方法验证服务器上是否配置了rstatd守护程序:
        ①使用rup命令,它用于报告计算机的各种统计信息,其中就包括rstatd的配置信息。使用命令rup 10.130.61.203,此处10.130.61.203是要监视的linux/Unix服务器的Ip,如果该命令返回相关的统计信息。则表示已经配置并且激活了rstatd守护进程;若未返回有意义的统计信息,或者出现一条错误报告,则表示rstatd守护进程尚未被配置或有问题。
        ②使用find命令
    #find / -name rpc.rstatd,该命令用于查找系统中是否存在rpc.rstatd文件,如果没有,说明系统没有安装rstatd守护程序。
        如果服务器上没有安装rstatd程序(一般来说LINUX都没有安装),需要下载一个包才有这个服务,包名字是rpc.rstatd-4.0.1.tar.gz. 这是一个源码,需要编译,下载并安装rstatd(可以在http://sourceforge.net/projects/rstatd这个地址下载)
    下载后,开始安装,安装步骤如下:
    tar -xzvf  rpc.rstatd-4.0.1.tar.gz
    cd  rpc.rstatd-4.0.1/
    ./configure  —配置操作
    make —进行编译
    make install —开始安装
    rpc.rstatd —启动rstatd进程

    2)安装完成后配置rstatd 目标守护进程xinetd,它的主配置文件是/etc/xinetd.conf ,它里面内容是一些如下的基本信息:
    #
    # xinetd.conf
    #
    # Copyright (c) 1998-2001 SuSE GmbH Nuernberg, Germany.
    # Copyright (c) 2002 SuSE Linux AG, Nuernberg, Germany.
    #
    defaults
    {
            log_type        = FILE /var/log/xinetd.log
            log_on_success  = HOST EXIT DURATION
            log_on_failure  = HOST ATTEMPT
          only_from       = localhost
            instances       = 30
            cps             = 50 10
    #
    # The specification of an interface is interesting, if we are on a firewall.
    # For example, if you only want to provide services from an internal
    # network interface, you may specify your internal interfaces IP-Address.
    #
         interface       = 127.0.0.1
    }
    includedir /etc/xinetd.d

    我们这里需要修改的是/etc/xinetd.d/下的三个conf文件 rlogin ,rsh,rexec 这三个配置文件,打这三个文件里的disable = yes都改成 disable = no ( disabled 用在默认的 {} 中禁止服务)或是把# default: off都设置成 on 这个的意思就是在xinetd启动的时候默认都启动上面的三个服务!
      说明:我自己在配置时,没有disable = yes这项,我就将# default: off改为:default: on,重启后(cd /etc/init.d/     ./xinetd restart)通过netstat -an |grep 514查看,没有返回。然后,我就手动在三个文件中最后一行加入disable = no,再重启xinetd,再使用netstat -an |grep 514查看,得到tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN结果,表明rsh服务器已经启动。

         只要保证Linux机器上的进程里有rstatd和xinetd这二个服务就可以用LR去监视了
    两点小的技巧:
    ①检查是否启动: rsh server 监听的TCP 是514。
    [root@mg04 root]# netstat -an |grep 514
    tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN
    如果能看到514在监听说明rsh服务器已经启动。
    ②检查是否启动: rstatd
    输入命令: rpcinfo -p
    如果能看到类似如下信息:
    程序 版本 协议 端口
    100001     udp    937  rstatd
    100001     udp    937  rstatd
    100001     udp    937  rstatd
    100001     udp    937  rstatd
    100001     udp    937  rstatd
    那就说明rstatd服务启动了,(当然这里也可以用ps ax代替)
    ③重起xinetd方法:
    在suse linux如下操作:
    cd /etc/init.d/
    ./xinetd restart
    看到网上有的地方说使用如下命令:
    # service xinetd reload
    # /sbin/service xinetd rstart
    不知道是在什么系统用的。
    ④安装rsh,和rsh-server两个服务包方法
    a. 卸载rsh
    # rpm –q rsh----------查看版本号
    # rpm -e 版本号---------卸载该版本。
    b.安装
    # rpm –ivh rsh-0.17-14.i386.rpm rsh-server-0.17-14.i386.rpm
    ⑤在启动rpc.rstatd时,会报错“Cannot register service: RPC: Unable to receive; errno = Ction refused”。
    解决方法如下:
    # /etc/init.d ./portmap start
    # /etc/init.d ./nfs start
    然后再次启动rpc.rstatd就好了。

    最后,在controller中,将UNIX resources拖放到右边窗口里面,右击鼠标选择Add Measurements,添加被监控linux的IP地址,然后选择需要监控的指标就可以了。

    三、监控UNIX
    lr监控UNIX ,UNIX先启动一rstatd服务
       以下是在IBM AIX系统中启动rstatd服务的方法:
    1、        使用telnet以root用户的身份登录入AIX系统
    2、        在命令行提示符下输入:vi /etc/inetd.conf
    3、        查找rstatd,找到
    #rstatd   sunrpc_udp     udp     wait    root    /usr/sbin/rpc.rstatd rstatd 100001 1-3
    4、将#去掉
    5、:wq保存修改结果
    6、命令提示符下输入:refresh –s inetd 重新启动服务。
    这样使用loadrunner就可以监视AIX系统的性能情况了。

    注:在HP UNIX系统上编辑完inetd.conf后,重启inetd服务需要输入inetd -c
    UNIX上也可以用rup命令查看rstatd程序是否被配置并激活
    若rstatd程序已经运行,重启时,先查看进程ps -ef |grep inet,然后杀掉进程,再refresh –s inetd进行重启

  • Jmeter请求_TCP协议

    2009-04-15 17:31:46

    最近在测试一款类QQ的聊天工具,需要对该聊天工具进行一些性能测试,因为发送请求的协议是使用TCP协议,所以就考虑使用jmeterTCP协议来试验是否能够成功,因为之前也没有使用过TCP协议,经过几天的实践,终于可以成功发送请求,并且收到服务器响应,相关记录如下:

    1. TCP协议

    2. 注意要点

      a 服务器地址和端口一定要填写正确

      b 要发送的文本框中输入tcp协议内容

      c.re_use connection表示重复发送连接请求

      d. 登录配置中的用户名和密码,如果TCP请求不需要用户吗密码,可以不用填写。

    3. 响应内容

      响应结果中会返回TCP请求的应答包,可以根据响应内容来查看请求是否正确被响应

     

  • LR错误解决_Invalid argument. Error code : 10022.

    2009-04-15 16:51:32

    问题描述:

    录制windows socket脚本回放成功
    在controller中运行脚本失败
    Action.c(6): Error : socket13 - Invalid argument. Error code : 10022

     

    Problem Description: Error: "socket<number> - Invalid argument. Error code : 10022" when creating a socket on the second iteration

    A Winsock script. replays fine on the first iteration, but has the following error during the second iteration on a lrs_create_socket statement:

    "Action.c(x): Error : socket<num> - Invalid argument. Error code : 10022."

    Diagnosis: This error indicates a failure to create a socket on the second iteration. This is because the socket is not closed on the first iteration.



    --------------------------------------------------------------------------------

    Solution: Verify that there is a corresponding lrs_close_socket statement in the Action section

    Before creating a new socket, the old socket should be closed. This means that if you recorded a script. into Vuser_init, Action, and Vuser_end sections, you need to make sure that the sockets that are opened in the Action section are also closed in the same section, because iterations only iterate the Action section.

    Example:
    The following code will cause a problem on socket 10 on the second iteration.

    Action{
       ...
       lrs_create_socket("socket10" , "TCP", "LocalHost=0”…,LAST );
       ...
    }

    Vuser_end{
       lrs_close_socket("socket10");
       ...
    }

    As a resolution, close the socket at the end of the Action section.

    Note:
    You may need to move all the lrs calls before the lrs_close_socket statement in the Action section as well.

    Example:
    Action{
       ...
       lrs_create_socket("socket10" , "TCP", "LocalHost=0”…,LAST );
       ...
       lrs_close_socket("socket10");
       return 0;
    }

  • 测试过程的一些思考

    2009-02-26 17:42:44

    一. 测试过程中的优点

      1. 对需求的测试

      测试人员在获得需求后,对需求进行正确性,一致性,完整性,可理解性等的检查,将检查过程中发现的问题都记录下来,然后在需求评审之前一到两天统一汇总到需求人员手中,需求人员对测试人员的问题进行解答,在进行需求评审会议的时候,需求人员在讲解完需求后,再针对测试提交的问题进行解答,解答完问题后,评审人员根据之前的情况再提问需求人员,这样可以提高评审会议的效率,同时,测试人员在检查需求,以及参与需求评审的时候,对需求的理解就会更深入。

      2. 测试风险的估计及应对

      写在测试计划中的测试风险,一定要有明确的可执行的应对方法。否则,如果在测试过程中出现了风险防范中列举的风险,但是没有可执行的方法,可能会严重影响到测试工作,最常见的的,比人测试人员的离职会不会对整个项目测试工作造成影响,有没有可以预防的方法,因为,新招聘一个测试人员参与项目,不但会严重影响到测试进度的,还可能出现因为交接不充分而出现测试遗漏。

      3. 测试时间安排

      测试计划中,测试时间安排是最重要的一个方面,要将测试时间安排的最合理主要有两个方面,一个是测试人员的能力,一个是测试工作量的估算,能力决定了测试人员擅长或者不擅长的方面,分配测试工作的时候,应该量体裁衣,每个测试工作人员做自己最擅长的部分,对于能力较弱的,可以分配一些简单的测试工作,但是量可以多一点。另一个方面是测试工作量的估算,它决定了测试时间安排的合理与否,测试项目可以分为好几个测试阶段,每个测试阶段的测试内容可以分为不同的测试任务,而每个测试任务又可以分为测试子任务,不能再分的测试子任务才能作为一个独立的测试任务,估算该测试任务需要花费的时间,在估算测试工作量的时候,还要考虑缓冲,测试工作量如果估算的十分精确,一定要有缓冲时间,因为,人不可能完全按照计划工作。

      4. 测试用例评审

      测试用例评审之前,主持人要做好准备工作,向测试用例提前发送给邀请的对象,同时在会议开始之前准备好会议室,电脑等,在测试用例评审过程中,因为测试用例很多,不能一一都过,最重要的是,测试人员在测试评审的时候,讲解清楚每个测试用例,或者每组测试用例是用来验证什么的,以及这些测试用例执行后能够发现哪些类型缺陷,讲解清楚自己的一个测试思路。

      5. 测试汇报进度

      从测试进入项目开始,测试人员最好是每天能够汇报当天的进度以及以后一两天的工作安排,汇报对象为测试组成员,测试经理,而测试经理则将每个人的汇报汇总后,发邮件给需求,开发,这样,一方面督促测试人员做好自己的工作,令一方面,也可以让其他项目相关人员了解测试人员的工作进度,更好的做好前提工作,因为测试人员的工作基本上是依赖于需求和开发的。

      6. 测试环境管理

      测试环境最好是有测试人员管理,这样,一方面可以锻炼测试人员的能力,更重要的是可以杜绝开发随便修改测试环境中的数据。保证测试环境的独立性。

      7. 版本控制

      如果测试人员测试的版本,每个版本之间是迭代开发完成的,则需要针对每个版本都做冒烟测试,对每个版本都要根据测试策略做完整的测试。如果每个版本提交比较频繁,测试人员只针对重要的版本进行测试,但针对每个版本都应该做版本验证测试,以免遗留有重要的缺陷。

  • 数据迁移测试方法粗谈

    2009-02-02 16:56:17

    数据迁移主要使用在新老系统到切换,主要有两种类型,一种是将老系统的数据全部迁移到新系统中,业务上只使用新系统,老系统不再使用,另外一种是,老系统的部分功能在新系统中暂时无法实现,但是在业务上需要使用新系统,需要将新系统中产生到数据导入到老系统到数据库中,做特殊用途。

    将老系统中到数据迁移到新系统中,主要到策略有:

    1.        查看老系统中到数据是否完全迁移到新系统中

    要保证新老系统到无缝切换,必须要保证数据的正确性,而将老系统中到数据迁移到新系统,首先就要保证所迁移的数据量是一致的,只要在保证数据量一致的情况下,才能进行其他方面到测试,如果数据量都不一致,说明迁移方法或者脚本就是错误到,需要寻找原因。

    2.        查看新老系统数据库表结构变化

    1)   哪些新表字段在老库中无数据,而新库必须有,这些数据无则默认给什么值

    2)   哪些数据字段一部分有数据,一部分无数据;迁移到新库中无数据这部分如何处理

    3)   旧数据库中的表关系到新库中的表关系有什么变化

    3.        查看新老系统中,相同字段不同状态的变化

    因为新老系统在业务表示上会有一定到差异,用来表示业务状态的标示也会存在有变化,就必须注意新老系统在表示相同业务状态的差异,一般,这种情况会做相应的映射,需要根据映射关系,检查迁移后的数据是否正确。

    4.        查看新老系统中各个字段转换是否正确

    在进行字段检查测试之前,需要准备测试数据,测试数据到准备最好是能够将每个字段到不同情况都考虑到,可以使用矩阵法,用最少的数据覆盖到最多的状态。准备好数据后,根据迁移规则,可以查看各字段迁移后到数据是否正确,一般来说,迁移规则有以下几种。

    1>      直接迁移,原来是什么就是什么,原封不动照搬过来,对这样的规则,如果数据源字段和目标字段长度或精度不符,需要特别注意看是否真的可以直接映射还是需要做一些简单运算,还要查看,迁移脚本中是否对长度或精度进行了处理,测试时,也需要准备长度精度不一致到数据进行测试,查看是否能够正确迁移。

    2>      字段运算,数据源的一个或多个字段进行数学运算得到的目标字段,这种规则一般对数值型字段而言。

    3>      参照转换,在转换中通常要用数据源的一个或多个字段作为Key,去一个关联数组中去搜索特定值,而且应该只能得到唯一值。一般来说,这样的主要适用于某些类似于id的字段

    4>      字符串处理,从数据源某个字符串字段中经常可以获取特定信息,例如身份证号。而且,经常会有数值型值以字符串形式体现。对字符串的操作通常有类型转换、字符串截取等。但是由于字符类型字段的随意性也造成了脏数据的隐患,所以在测试这种情况的时候,一定要考虑异常情况。

    5>      空值判断,对于老系统中空值字段,不能简单的认为迁移后还是空值,需要根据实际的情况,考虑该字段在新库中应该为哪个字段,还要考虑,如果老系统中该字段不为空的情况。

    6>      日期转换,需要考虑新老系统对日期到不同表示方法。

    7>      聚集运算,对于事实表中的度量字段,他们通常是通过数据源一个或多个字段运用聚集函数得来的,这些聚集函数为SQL标准中,包括sum,count,avg,min,max

    8>      既定取值,这种规则和以上各种类型规则的差别就在于它不依赖于数据源字段,对目标字段取一个固定的或是依赖系统的值。

    5.        查看迁移后的数据在业务逻辑上是否正确

        使用从老系统中迁移过来的数据,在业务系统中进行流程测试,功能测试确保迁移后到数据可用。

    将新系统中到数据迁移到老系统中,一般不会全部迁移,可能就是将部分表迁移过去,使得老系统可以用新系统中到这些数据进行相关的统计,迁移到主要方式是批量迁移,就是说,在一定的时间范围内,运行一次脚本,将新系统中到数据迁移到老系统中,主要到测试策略如下:

    1.        查看时间段内所有数据都进行了迁移操作

    迁移是将新系统中一定时间范围内有变化的数据反映到老系统,因此,需要测试在这个时间段内有新系统中有变化的数据都正确反应到老系统中,一般来说,数据迁移,会有一个表专门用来记录在新系统中数据到变化情况,可以通过查看该日志表,得到有变化的数据记录,然后可以在新系统中对应进行检查。

    2.        查看新增的数据是否能够迁移

    因为是批量到迁移,需要确保新系统中新增到数据能够迁移到老系统中去,可以根据ID,唯一确定新系统中生成的数据迁移到了老系统。

    3.        查看修改到数据是否能够真确反映到老系统中

    新系统中,不可避免的会对数据进行修改操作修改操作后的数据,相应的,老系统中对应的数据也需要改变,就需要测试,如果新系统中的数据修改了,执行脚本后,老系统中到数据是否会做同样的修改。

    4.        查看删除数据是否正确反映到老系统中

    新系统中,对数据进行删除操作,该数据对应到老系统中的数据同样也需要被删除。

    5.        查看迁移后各字段是否正确

    字段对照检查,方法和前面的老系统迁移到新系统中一样。

    6.        大数据量测试

    因为是批量进行迁移,可能在数据量较大的情况,此时,如果迁移脚本关联操作较多,可能催存在脚本执行时间段内不能完成所有数据到迁移,导致本次本次迁移的数据没有完成,到下一次执行脚本时,又有数据没有迁移完成,就会有大量到数据不能完成迁移操作,此时就需要优化迁移脚本,或者增加脚本定时钟的时间。大数据量的测试,还需要关注,在数据量较大到情况下,迁移的数据是否会出现错误。

    7.        业务测试

                 因为新系统的数据库表结构以及字段表示可能和老系统不一致,需要用迁移到老系统中的数据进行功能测试,流程测试,确保数据可用。

    8.        不进行迁移的字段确认

          因为新系统的数据库表结构以及字段表示可能和老系统不一致,新系统中部分字段可能在老系统中找不到对应的字段,就不需要迁移,这一部分也需要进行验证,确保不会将不迁移的字段数据迁移到其他的字段中。

    9.        字段长度不一致检查

          新系统中字段长度和老系统对应字段长度不一致,要么无法迁移,要么就需要进行截取,如果不能迁移,就需要有错误日志,确定哪些字段不能迁移,如果是截取,则需要确认,截取的长度是否真确,如果截取了,是否会在业务上造成影响

    对于数据迁移的测试,个人觉得需要关注两个方面,一个是从业务上关注,迁移后的数据在业务流程上应该是可用的,也不会对现有到业务造成影响,另外一个就是迁移后到数据应该是完整的,正确的,可用的首先就需要关注迁移规则是不是正确的,如果迁移规则是错误的,迁移后的数据就算是符合迁移规则了,也是不正确的。

  • 用jmeter测试https应用

    2008-12-17 15:16:01

      该文为转载

     

        实验室的项目是做关于web servicesecurity产品,主要是对soap消息进行加密签名。上一次的性能测试是将单纯调用web service和应用我们的security产品后的web service进行对比,然而差距还是相当明显的,尤其是在高并发的时候,毕竟中间的加密和签名过程是相当消耗时间的。上次review的时候,老师就说性能有很大的程度可以提高,我本来想说基本没太多的空间可以优化(除了之后会加入的线程池,应该会有小幅度性能提升),但是苦于没有数据支持。正好这两天为了准备开题,一直在看一些文章,看到网上有人提到,SSL + WS-Security = Web Service安全保障,主张用https的方式来传输soap消息。虽然不是什么很好的方法,不过不是正好拿来作为产品测试对比的对象嘛。

        tomcat上已经配置好了axis,通过http访问soap消息是没有问题了。但是还没有配置https,所以按着官方文档开始干活了。首先用keytool生成服务器段的keystore

    keytool -genkey -alias tomcat -keystore ktomcat.keystore

        注意,alias的密码要与keystore的密码一致,tomcat文档上是这么说的。接着是修改了server.xml:

    <Connector
               port="8443" protocol="HTTP/1.1" minSpareThreads="5" maxSpareThreads="75"
               enableLookups="true" disableUploadTimeout="true"
               acceptCount="100"  maxThreads="200"
               scheme="https" secure="true" SSLEnabled="true"
               keystoreFile="ktomcat.keystore" keystorePass="changeit"
               clientAuth="false" sslProtocol="TLS"/>

        重启tomcat之后,输入https://localhost:8443进行验证(注意是8443哦,我一开始居然傻乎乎的输入8080^_^

        接着设置客户端的trustStorejmeter需要它来信任tomcat服务器段的证书

    keytool -export -alias tomcat -keystore ktomcat.keystore -file tomcat.crt
    keytool -import -alias tomcat -file tomcat.crt -keystore tclient.keystore

        tomcat上的https配置成功之后,就开始jmeter的配置了,默认情况下用jmeter是不可以访问我们配置的https应用的,不过却可以访问像google等网站上的https应用,原因很简单,我们自己生成的证书是不被信任的。jmeter的官方网站有一个很大的陷阱,上面说只要修改jmeter.properties参数,将SSL Configuration部分内的注释去掉就可以了,如下

    #---------------------------------------------------------------------------
    # SSL configuration
    #---------------------------------------------------------------------------

    #Classname of the ssl provider to be used (to enable testing of https urls)
    #And the package name where Stream Handlers can be found
    #These provided defaults can be uncommented, and they will work if you are using
    #Sun's JSSE implementation.

    ssl.provider=com.sun.net.ssl.internal.ssl.Provider
    ssl.pkgs=com.sun.net.ssl.internal.www.protocol

    #The location of the truststore (trusted certificates) and keystore ( if other than the default.
    #you can uncomment this and change the path to the correct location.
    javax.net.ssl.trustStore=/home/flyerhzm/software/jakarta-jmeter-2.2/tclient.keystore
    javax.net.ssl.keyStore=/home/flyerhzm/software/jakarta-jmeter-2.2/kclient.keystore

    #The password to your keystore
    javax.net.ssl.keyStorePassword=changeit

        不过结果还是失败,尝试了好多次,总是报SSLHandshakeException。如果是通过浏览器访问的话,浏览器都会提醒你对方的证书不合法,是否要信任它,但是java是不会询问你,而是直接抛出异常。但是如果设置了trustStore的话,就会信任对方的证书啦,太奇怪了。

        google了一下有关SSLHandshakeException,网上有说可以用-D方式添加应用参数,于是打开了jmter启动文件,修改最后一句话为:

    java $JVM_ARGS $ARGS -jar `dirname $0`/ApacheJMeter.jar -Djavax.net.ssl.trustStore=/home/flyerhzm/software/jakarta-jmeter-2.2/tclient.keystore -Djavx.net.ssl.trustStorePassword=changeit "$@"

        居然成功了,呵呵。可恶,配置文件jmeter.properties居然不起作用,害我辛苦到现在。

        趁热打铁,测试了一下通过https访问web service,果然比应用我们的security产品要多消耗1倍多的时间,赞,终于有数据可以说服老师了,哈哈。

     

1062/6<123456>
Open Toolbar