zoukankan      html  css  js  c++  java
  • 使用 Gateling 进行性能测试

    Gatling 是一个简便的性能测试工具,用它编写性能测试脚本速度快易上手。本文将深入探究 Gatling 的功能以及如何更好地使用。

    在程序部署到生产环境前,有多少人会创建自动化性能测试?通常,开发人员更重视功能测试,至少会进行一些简单的单元测试和集成测试。但是与未检测到的业务错误相比,有时候性能泄露造成的问题更严重。因为后者会影响整个系统,不仅仅是某个业务流程。

    就个人而言,我一直对自己开发的程序进行性能测试,但是从来没有把它作为持续集成的一部分运行。当然,这是几年前的情况,那时候我的知识和经验都略显不足。最近,我开始对性能测试相关的主题非常感兴趣,部分原因是公司的应用程序存在性能问题。问题的关键是找到合适的工具。也许很多人听说过 JMeter,这里会介绍它的竞品——Gatling。它会生成各种内容丰富的报告,其中包含了测试用例执行过程中收集的所有指标。这些功能比 JMeter 似乎更好。 

    在开始介绍 Gatling 之前,让我们先聊聊理论。首先,性能测试有两种类型:负载测试和压力测试。负载测试会验证,在特定时间内有大量客户端同时发起请求情况下的系统功能。这种测试的主要目标是模拟生产环境中可能出现的流量。压力测试会执行负载测试,把应用程序推向极限,查看重负载情况下程序的表现。

    Gatling是什么? 

    Gatling 是一个用 Scala 编写的负载测试工具,功能强大。它完全支持 HTTP 协议,也可以用来测试 JDBC 连接和 JMS。使用 Gatling 时,需要用 Scala dsl 代码定义测试场景。值得一提的是,Gatling 生成的 HTML 负载报告内容全面,并且提供了 Gradle、Maven 和 Jenkins 插件方便集成。

    构建示例应用

    开始测试前,需要准备测试应用。示例程序非常简单,源代码可以在 GitHub 上找到(github.com/piomin/sample-gatling-load-tests)。它提供了一组 CRUD 操作的 RESTful HTTP API,在可以数据库中新增和搜索 Entity。数据库用 Postgres,基于 Spring Boot 构建,使用Spring Data 实现持久层。

    plugins {
       id 'org.springframework.boot' version '1.5.9.RELEASE'
    }
    dependencies {
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
    compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4'
    testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
    }

    Person entity映射到 person 表。

    @Entity
    @SequenceGenerator(name = "seq_person", initialValue = 1, allocationSize = 1)
    public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_person")
    private Long id;
    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;
    @Column(name = "birth_date")
    private Date birthDate;
    @Embedded
    private Address address;
    // ...
    }

    数据库连接设置和 Hibernate 属性配置在 application.yml 中。 

    spring:
     application:
       name: gatling-service
     datasource:
       url: jdbc:postgresql://192.168.99.100:5432/gatling
       username: gatling
       password: gatling123
     jpa:
       properties:
         hibernate:
           hbm2ddl:
             auto: update
    server:
     port: 8090
     

    正如之前提到的,示例程序提供了在数据库中添加、搜索 person 的 API,下面是 Spring REST controller 实现。

    @RestController
    @RequestMapping("/persons")
    public class PersonsController {
    private static final Logger LOGGER = LoggerFactory.getLogger(PersonsController.class);
    @Autowired
    PersonsRepository repository;
    @GetMapping function(){ //外汇跟单www.gendan5.com
    public List
    <Person> findAll() {
     return (List
     <Person>) repository.findAll();
       }
       @PostMapping
       public Person add(@RequestBody Person person) {
       Person p = repository.save(person);
       LOGGER.info("add: {}", p.toString());
       return p;
       }
       @GetMapping("/{id}")
       public Person findById(@PathVariable("id") Long id) {
       LOGGER.info("findById: id={}", id);
       return repository.findOne(id);
       }
       }

    运行数据库

    开发示例程序的下一步是运行数据库,最合适的方式是 Docker image。下面的 Docker 命令会启动一个 Postgres container,完成 gatling 用户和数据库初始化。 

    docker run -d --name postgres -e POSTGRES_DB=gatling -e POSTGRES_USER=gatling -e POSTGRES_PASSWORD=gatling123 -p 5432:5432 postgres 

    设计测试场景 

    每个 Gatling test suite 都要继承 Simulation 类,使用 Gatling Scala DSL 声明一系列测试场景。我们的目标是启动30个客户端,同时发送1000次请求。首先,客户端通过 POST /persons 方法向数据库添加 person。然后,调用 GET /persons/{id}搜索 person。总共向应用程序发送6万次请求:3万次 POST,3万次 GET。下面代码展示了测试场景,非常简单。在 src/test/scala 目录下可以找到 ApiGatlingSimulationTest。 

    class ApiGatlingSimulationTest extends Simulation {
     val scn = scenario("AddAndFindPersons").repeat(1000, "n") {
           exec(
             http("AddPerson-API")
               .post("http://localhost:8090/persons")
               .header("Content-Type", "application/json")
               .body(StringBody("""{"firstName":"John${n}","lastName":"Smith${n}","birthDate":"1980-01-01", "address": {"country":"pl","city":"Warsaw","street":"Test${n}","postalCode":"02-200","houseNo":${n}}}"""))
               .check(status.is(200))
           ).pause(Duration.apply(5, TimeUnit.MILLISECONDS))
     }.repeat(1000, "n") {
           exec(
             http("GetPerson-API")
               .get("http://localhost:8090/persons/${n}")
               .check(status.is(200))
           )
     }
     setUp(scn.inject(atOnceUsers(30))).maxDuration(FiniteDuration.apply(10, "minutes"))
    }
     

    为了在项目中启用 Gatling 框架,还需要在 Gradle 构建文件中添加依赖。 

    testCompile group: 'io.gatling.highcharts', name: 'gatling-charts-highcharts', version: '2.3.0' 

    运行测试 

    通过一些 Gradle 插件可以在项目构建期间运行测试。但是,也可用 io.gatling.app.Gatling 类定义简单的 gradle 任务。 

    task loadTest(type: JavaExec) {
      dependsOn testClasses
      description = "Load Test With Gatling"
      group = "Load Test"
      classpath = sourceSets.test.runtimeClasspath
      jvmArgs = [
           "-Dgatling.core.directory.binaries=${sourceSets.test.output.classesDir.toString()}"
      ]
      main = "io.gatling.app.Gatling"
      args = [
              "--simulation", "pl.piomin.services.gatling.ApiGatlingSimulationTest",
              "--results-folder", "${buildDir}/gatling-results",
              "--binaries-folder", sourceSets.test.output.classesDir.toString(),
              "--bodies-folder", sourceSets.test.resources.srcDirs.toList().first().toString() + "/gatling/bodies",
      ]
    }

    使用 gradle loadTest 执行定义好的 Gradle 任务。当然,运行测试之前需要启动应用程序,在 IDE 中启动 main class pl.piomin.services.gatling.ApiApplication 或者执行 java -jar build/libs/sample-load-test-gatling.jar 命令。 

    测试报告 

    测试执行完毕会以文本形式打印报告。 

    ================================================================================
    ---- Global Information --------------------------------------------------------
    > request count                                      60000 (OK=60000  KO=0     )
    > min response time                                      2 (OK=2      KO=-     )
    > max response time                                   1338 (OK=1338   KO=-     )
    > mean response time                                    80 (OK=80     KO=-     )
    > std deviation                                        106 (OK=106    KO=-     )
    > response time 50th percentile                         50 (OK=50     KO=-     )
    > response time 75th percentile                         93 (OK=93     KO=-     )
    > response time 95th percentile                        253 (OK=253    KO=-     )
    > response time 99th percentile                        564 (OK=564    KO=-     )
    > mean requests/sec                                319.149 (OK=319.149 KO=-     )
    ---- Response Time Distribution ------------------------------------------------
    > t < 800 ms                                         59818 (100%) > 800 ms < t < 1200 ms                                 166 (  0%) > t > 1200 ms                                           16 (  0%)
    > failed                                                 0 (  0%)
    ================================================================================

    但是,Gatling 最擅长的是报告图表。生成的 HTML 报告在 build/gatling-results 目录下。第一个报告展示了全局信息,包含请求总数和最大响应时间(百分比)。例如,95%的 GetPerson API 请求的最大响应时间为206ms。

    可以在报告中查看所有请求,也可以过滤结果,只查看选定的 API。下面的图片只展示了 GetPerson API。 

    这张图展示了平均响应时间百分比。 

     

    这张图中的时间轴表示平均响应时间。此外,该时间轴还按百分比展示了统计信息。 

     

    这张图展示了应用程序每秒钟成功处理的请求数。

  • 相关阅读:
    HTML5学习之画布和SVG(四)
    HTML5学习之视频与音频(三)
    HTML5学习之智能表单(二)
    HTML5学习之文档结构和语义(一)
    WCF分布式开发必备知识(3):Web Service 使用
    比较各大挪动门户网站淘宝、京东、网易、新浪、腾讯meta标签的异同
    jQuery Mobile学习之grid、等待显示的ajax效果、页面跳转、页面跳转传递参数等(二)
    jQuery Moblie 学习之page、button、theme、panel、listview、controlgroup、navbar等(一)
    使用Modernizr探测HTML5/CSS3新特性(转载)
    设计模式学习之模板方法模式(TemplateMethod,行为型模式)(9)
  • 原文地址:https://www.cnblogs.com/gendan5/p/11763742.html
Copyright © 2011-2022 走看看