Gatling でぶっ放せ！

## What's this?

![gatling00.png](https://qiita-image-store.s3.amazonaws.com/0/39751/649cc7bc-003e-a617-5178-0472053413fb.png)
Java/Scala 製の負荷テストツール   [http://gatling.io][link-01] 


* Install Java
* Install/Setup Gatling
* 負荷テスト実施
* Install/Setup nginx
* 負荷テスト結果をブラウザで確認

## Install java

    # yum install java
    ==================================================================================================================================
     Package                                   Arch                 Version                               Repository             Size
    ==================================================================================================================================
    Installing:
     java-1.8.0-openjdk                        x86_64               1:1.8.0.71-2.b15.el7_2                updates               217 k
    Installing for dependencies:
     giflib                                    x86_64               4.1.6-9.el7                           base                   40 k
     java-1.8.0-openjdk-headless               x86_64               1:1.8.0.71-2.b15.el7_2                updates                31 M
     javapackages-tools                        noarch               3.4.1-11.el7                          base                   73 k
     libICE                                    x86_64               1.0.9-2.el7                           base                   65 k
     libSM                                     x86_64               1.2.2-2.el7                           base                   39 k
     libXext                                   x86_64               1.3.3-3.el7                           base                   39 k
     libXfont                                  x86_64               1.5.1-2.el7                           base                  150 k
     libXi                                     x86_64               1.7.4-2.el7                           base                   40 k
     libXrender                                x86_64               0.9.8-2.1.el7                         base                   25 k
     libXtst                                   x86_64               1.2.2-2.1.el7                         base                   20 k
     libfontenc                                x86_64               1.1.2-3.el7                           base                   30 k
     lksctp-tools                              x86_64               1.0.13-3.el7                          base                   87 k
     python-javapackages                       noarch               3.4.1-11.el7                          base                   31 k
     python-lxml                               x86_64               3.2.1-4.el7                           base                  758 k
     ttmkfdir                                  x86_64               3.0.9-42.el7                          base                   48 k
     tzdata-java                               noarch               2015g-1.el7                           base                  176 k
     xorg-x11-font-utils                       x86_64               1:7.5-20.el7                          base                   87 k
     xorg-x11-fonts-Type1                      noarch               7.5-9.el7                             base                  521 k

    Transaction Summary
    ==================================================================================================================================
    Install  1 Package (+18 Dependent packages)


## Install/Setup Gatling

#### Download

[http://gatling.io/#/download][link-02]

    # wget https://oss.sonatype.org/content/repositories/snapshots/io/gatling/highcharts/gatling-charts-highcharts-bundle/2.2.0-SNAPSHOT/gatling-charts-highcharts-bundle-2.2.0-20160115.153229-389-bundle.zip
    # unzip gatling-charts-highcharts-bundle-2.2.0-20160115.153229-389-bundle.zip
    # cd gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT

#### Create simulation file

Sample simulation file が user-files/simulations/ にあるので、これを参考に作ってみる。

    # tree user-files/simulations/
    user-files/simulations/
    └── computerdatabase
        ├── advanced
        │   ├── AdvancedSimulationStep01.scala
        │   ├── AdvancedSimulationStep02.scala
        │   ├── AdvancedSimulationStep03.scala
        │   ├── AdvancedSimulationStep04.scala
        │   └── AdvancedSimulationStep05.scala
        └── BasicSimulation.scala

    2 directories, 6 files

Sample をコピーして、

    # cd user-files/simulations/
    # cp computerdatabase/BasicSimulation.scala TestSimulation.scale

    # vi TestSimulation.scale

とりあえず Simple にこんな感じで。

    # cat TestSimulation.scala
    import io.gatling.core.Predef._
    import io.gatling.http.Predef._
    import scala.concurrent.duration._

    class TestSimulation extends Simulation {

      val httpConf = http
        .baseURL("http://<負荷テスト対象の URL>") // Here is the root for all relative URLs
        .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") // Here are the common headers
        .doNotTrackHeader("1")
        .acceptLanguageHeader("en-US,en;q=0.5")
        .acceptEncodingHeader("gzip, deflate")
        .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0")

      val headers_10 = Map("Content-Type" -> "application/x-www-form-urlencoded") // Note the headers specific to a given request

      val scn = scenario("Test Scenario") // A scenario is a chain of requests and pauses
        .exec(http("request_1")
          .get("/"))
        .pause(7) // Note that Gatling has recorded real time pauses

      setUp(scn.inject(
        rampUsers(600) over(60)
      ).protocols(httpConf))
    }


##### 最後の部分 Injection の意味

* rampUsers(600) over(60 seconds))                 :  60 秒間に 600 回アクセス
* rampUsersPerSec(1) to (100) during (60 seconds)  :  60 秒間で 1〜100 までユーザ増やしてアクセス
* constantUsersPerSec(10) during(60 seconds)       :  1 秒間で 10 ユーザのアクセスを 60 秒キープ

その他はこちらを参考に。
[http://gatling.io/docs/2.1.7/general/simulation_setup.html][link-03]

〜〜 例 〜〜

    setUp(
      scn.inject(
        nothingFor(4 seconds), // 1
        atOnceUsers(10), // 2
        rampUsers(10) over(5 seconds), // 3
        constantUsersPerSec(20) during(15 seconds), // 4
        constantUsersPerSec(20) during(15 seconds) randomized, // 5
        rampUsersPerSec(10) to 20 during(10 minutes), // 6
        rampUsersPerSec(10) to 20 during(10 minutes) randomized, // 7
        splitUsers(1000) into(rampUsers(10) over(10 seconds)) separatedBy(10 seconds), // 8
        splitUsers(1000) into(rampUsers(10) over(10 seconds)) separatedBy atOnceUsers(30), // 9
        heavisideUsers(1000) over(20 seconds) // 10
      ).protocols(httpConf)
    )


> The building blocks for profile injection the way you want are:
>
> 1. nothingFor(duration): Pause for a given duration.
> 2. atOnceUsers(nbUsers): Injects a given number of users at once.
> 3. rampUsers(nbUsers) over(duration): Injects a given number of users with a linear ramp over a given duration.
> 4. constantUsersPerSec(rate) during(duration): Injects users at a constant rate, defined in users per second, during a given duration. Users will be injected at regular intervals.
> 5. constantUsersPerSec(rate) during(duration) randomized: Injects users at a constant rate, defined in users per second, during a given duration. Users will be injected at randomized intervals.
> 6. rampUsersPerSec(rate1) to (rate2) during(duration): Injects users from starting rate to target rate, defined in users per second, during a given duration. Users will be injected at regular intervals.
> 7. rampUsersPerSec(rate1) to(rate2) during(duration) randomized: Injects users from starting rate to target rate, defined in users per second, during a given duration. Users will be injected at randomized intervals.
> 8. heavisideUsers(nbUsers) over(duration): Injects a given number of users following a smooth approximation of the heaviside step function stretched to a given duration.
> 9. splitUsers(nbUsers) into(injectionStep) separatedBy(duration): Repeatedly execute the defined injection step separated by a pause of the given duration until reaching nbUsers, the total number of users to inject.
> 10. splitUsers(nbUsers) into(injectionStep1) separatedBy(injectionStep2): Repeatedly execute the first defined injection step (injectionStep1) separated by the execution of the second injection step (injectionStep2) until reaching nbUsers, the total number of users to inject.




## Run Gatling

最終的に HTML ファイルが結果として出力される。

    # pwd
    /PATH/TO/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT

    # bin/gatling.sh
    GATLING_HOME is set to /PATH/TO/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT
    Choose a simulation number:
         [0] TestSimulation
         [1] computerdatabase.BasicSimulation
         [2] computerdatabase.advanced.AdvancedSimulationStep01
         [3] computerdatabase.advanced.AdvancedSimulationStep02
         [4] computerdatabase.advanced.AdvancedSimulationStep03
         [5] computerdatabase.advanced.AdvancedSimulationStep04
         [6] computerdatabase.advanced.AdvancedSimulationStep05
    0
    Select simulation id (default is 'testsimulation'). Accepted characters are a-z, A-Z, 0-9, - and _

    Select run description (optional)

    Simulation TestSimulation started...

    ================================================================================
    2016-01-30 01:56:38                                           5s elapsed
    ---- Test Scenario -------------------------------------------------------------
    [###--                                                                     ]  4%
              waiting: 565    / active: 10     / done:25
    ---- Requests ------------------------------------------------------------------
    > Global                                                   (OK=35     KO=0     )
    > request_1                                                (OK=35     KO=0     )
    ================================================================================

    〜〜 省略 〜〜

    ================================================================================
    2016-01-30 01:57:35                                          62s elapsed
    ---- Test Scenario -------------------------------------------------------------
    [##########################################################################]100%
              waiting: 0      / active: 0      / done:600
    ---- Requests ------------------------------------------------------------------
    > Global                                                   (OK=600    KO=0     )
    > request_1                                                (OK=600    KO=0     )
    ================================================================================

    Simulation TestSimulation completed in 61 seconds
    Parsing log file(s)...
    Parsing log file(s) done
    Generating reports...

    ================================================================================
    ---- Global Information --------------------------------------------------------
    > request count                                        600 (OK=600    KO=0     )
    > min response time                                      2 (OK=2      KO=-     )
    > max response time                                     52 (OK=52     KO=-     )
    > mean response time                                     3 (OK=3      KO=-     )
    > std deviation                                          2 (OK=2      KO=-     )
    > response time 50th percentile                          3 (OK=3      KO=-     )
    > response time 75th percentile                          3 (OK=3      KO=-     )
    > mean requests/sec                                9836.066 (OK=9836.066 KO=-     )
    ---- Response Time Distribution ------------------------------------------------
    > t < 800 ms                                           600 (100%)
    > 800 ms < t < 1200 ms                                   0 (  0%)
    > t > 1200 ms                                            0 (  0%)
    > failed                                                 0 (  0%)
    ================================================================================

    Reports generated in 0s.
    Please open the following file: /PATH/TO/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT/results/testsimulation-1454086593318/index.html

.class は target/test-classes/ の下に作成される。

    # ls -l target/test-classes/TestSimulation.class
    -rw-r--r-- 1 root root 6140 Jan 30 01:55 target/test-classes/TestSimulation.class

## Install/Setup nginx

出力された結果をそのまま確認しても問題ないが、
複数回実施した結果をブラウザで直接すぐに確認する為に nginx を設定

##### Install

    # yum install nginx

    ==================================================================================================================================
     Package                                   Arch                     Version                          Repository              Size
    ==================================================================================================================================
    Installing:
     nginx                                     x86_64                   1:1.6.3-7.el7                    epel                   507 k
    Installing for dependencies:
     GeoIP                                     x86_64                   1.5.0-9.el7                      base                   709 k
     fontconfig                                x86_64                   2.10.95-7.el7                    base                   228 k
     fontpackages-filesystem                   noarch                   1.44-8.el7                       base                   9.9 k
     gd                                        x86_64                   2.0.35-26.el7                    base                   146 k
     gperftools-libs                           x86_64                   2.4-7.el7                        base                   272 k
     libXpm                                    x86_64                   3.5.11-3.el7                     base                    54 k
     libunwind                                 x86_64                   1.1-5.el7                        base                    56 k
     libxslt                                   x86_64                   1.1.28-5.el7                     base                   242 k
     nginx-filesystem                          noarch                   1:1.6.3-7.el7                    epel                    15 k

    Transaction Summary
    ==================================================================================================================================
    Install  1 Package (+9 Dependent packages)

##### 結果を格納する Directory 作成

    # mkdir /usr/share/nginx/html/gatling

##### autoindex を enable にしておく

    # vi /etc/nginx/nginx.conf

            location / {
                autoindex on;   <-- ADD
            }

##### start nginx

    # systemctl start nginx
    # systemctl enable nginx

## Gateing の結果を nginx へコピー

    # cp -rp /PATH/TO/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT/results/testsimulation-1454086593318 /usr/share/nginx/html/gatling/

## Add http permit policy to firewalld

    # firewall-cmd --zone=public --add-service=http --permanent
    success

    # firewall-cmd --reload
    success

    # firewall-cmd --list-service
    http ssh

## 結果

http://x.x.x.x/gatling/

![gatling01.png](https://qiita-image-store.s3.amazonaws.com/0/39751/1896d0e7-3a2b-2de0-f902-fa84e94d9706.png)

![gatling02.png](https://qiita-image-store.s3.amazonaws.com/0/39751/678a9550-8a23-9d1d-7278-102c661c3034.png)


## Environment

##### os

    # cat /etc/redhat-release
    CentOS Linux release 7.1.1503 (Core)

##### java

    # /usr/bin/java -version
    openjdk version "1.8.0_71"
    OpenJDK Runtime Environment (build 1.8.0_71-b15)
    OpenJDK 64-Bit Server VM (build 25.71-b15, mixed mode)

##### nginx

    # nginx -v
    nginx version: nginx/1.6.3

##### gatling

    gatling-charts-highcharts-bundle-2.2.0-20160115.153229-389-bundle.zip

## Reference

[http://gatling.io/#/docs][link-04]

[link-01]:http://gatling.io
[link-02]:http://gatling.io/#/download
[link-03]:http://gatling.io/docs/2.1.7/general/simulation_setup.html
[link-04]:http://gatling.io/#/docs