Performance and stability testing \w Gatling

591 vues

Publié le

Explore how Gatling can help with performance & stability testing in TDD fashion.

Publié dans : Technologie
0 commentaire
2 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
591
Sur SlideShare
0
Issues des intégrations
0
Intégrations
2
Actions
Partages
0
Téléchargements
19
Commentaires
0
J’aime
2
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Performance and stability testing \w Gatling

  1. 1. With Gatling Performance & Stability Testing
  2. 2. Development Testing
  3. 3. @Me Dmitry Vrublevsky, Software developer @ /in/dmitryvrublevsky
  4. 4. Roadmap - Mission overview - Gatling introduction - Some usage example
  5. 5. Mission
  6. 6. Given: Graph database (Neo4j) Challenge: execute query as FAST as we can
  7. 7. Neo4j - Written in Java - Native graph storage - Extendable
  8. 8. So? - Default API is too slow - Implement custom extension - Control all the things
  9. 9. 1. Developed 2. Deployed 3. ??? 4. Success!
  10. 10. Performance
  11. 11. Specification Do “X” operations in “Y” seconds
  12. 12. Specification Do “10000” query operations in “10” seconds
  13. 13. POST /extension/query Body: “MATCH (root)-[:HAS*]->(child)” Response: { // JSON data }
  14. 14. Client LB DB1 DB2 DB3 - our extension
  15. 15. Problems?
  16. 16. Client LB DB1 DB2 DB3 - our extension - possible problem
  17. 17. Gatling http://gatling.io
  18. 18. Load testing framework
  19. 19. Free & Open source
  20. 20. High performance
  21. 21. Friendly DSL Nice html reports
  22. 22. Coding ?
  23. 23. Bundle 1. Download bundle 2. Extract 3. Ready http://gatling.io/#/download
  24. 24. Optional - Maven integration - SBT plugin - Gradle plugin
  25. 25. package com.neueda.example
 
 import io.gatling.core.Predef._
 import io.gatling.http.Predef._
 import scala.concurrent.duration._
 
 class Example extends Simulation {
 val httpConf = http.baseURL("http://www.example.com")
 
 val example = scenario("Example")
 .exec(
 http("get_example_index")
 .get("/")
 .check(status.is(200))
 )
 
 setUp(
 example.inject(rampUsers(10) over (10 seconds))
 ).protocols(httpConf)
 }
  26. 26. package com.neueda.example
 
 import io.gatling.core.Predef._
 import io.gatling.http.Predef._
 import scala.concurrent.duration._

  27. 27. class Example extends Simulation {
 
 }
  28. 28. val httpConf = http.baseURL("http://www.example.com")
  29. 29. val example = scenario("Example")
  30. 30. http("get_example_index")
 .get("/")
 .check(status.is(200))
  31. 31. setUp(
 ).protocols(httpConf)
  32. 32. example.inject( rampUsers(10) over (10 seconds) )
  33. 33. package com.neueda.example
 
 import io.gatling.core.Predef._
 import io.gatling.http.Predef._
 import scala.concurrent.duration._
 
 class Example extends Simulation {
 val httpConf = http.baseURL("http://www.example.com")
 
 val example = scenario("Example")
 .exec(
 http("get_example_index")
 .get("/")
 .check(status.is(200))
 )
 
 setUp(
 example.inject(rampUsers(10) over (10 seconds))
 ).protocols(httpConf)
 }
  34. 34. http://gatling.io/docs/2.1.4/cheat-sheet.html
  35. 35. ================================================================================ 2015-04-07 23:02:54 5s elapsed ---- Example ------------------------------------------------------------------- [##################################### ] 50% waiting: 5 / running: 0 / done:5 ---- Requests ------------------------------------------------------------------ > Global (OK=5 KO=0 ) > get_example_index (OK=5 KO=0 ) ================================================================================ ================================================================================ ---- Global Information -------------------------------------------------------- > request count 10 (OK=10 KO=0 ) > min response time 255 (OK=255 KO=- ) > max response time 302 (OK=302 KO=- ) > mean response time 274 (OK=274 KO=- ) > std deviation 13 (OK=13 KO=- ) > response time 95th percentile 293 (OK=293 KO=- ) > response time 99th percentile 300 (OK=300 KO=- ) > mean requests/sec 1.08 (OK=1.08 KO=- ) ---- Response Time Distribution ------------------------------------------------ > t < 800 ms 10 (100%) > 800 ms < t < 1200 ms 0 ( 0%) > t > 1200 ms 0 ( 0%) > failed 0 ( 0%) ================================================================================
  36. 36. ================================================================================ 2015-04-07 23:02:54 5s elapsed ---- Example ------------------------------------------------------------------- [##################################### ] 50% waiting: 5 / running: 0 / done:5 ---- Requests ------------------------------------------------------------------ > Global (OK=5 KO=0 ) > get_example_index (OK=5 KO=0 ) ================================================================================ ================================================================================ ---- Global Information -------------------------------------------------------- > request count 10 (OK=10 KO=0 ) > min response time 255 (OK=255 KO=- ) > max response time 302 (OK=302 KO=- ) > mean response time 274 (OK=274 KO=- ) > std deviation 13 (OK=13 KO=- ) > response time 95th percentile 293 (OK=293 KO=- ) > response time 99th percentile 300 (OK=300 KO=- ) > mean requests/sec 1.08 (OK=1.08 KO=- ) ---- Response Time Distribution ------------------------------------------------ > t < 800 ms 10 (100%) > 800 ms < t < 1200 ms 0 ( 0%) > t > 1200 ms 0 ( 0%) > failed 0 ( 0%) ================================================================================
  37. 37. Reports o/
  38. 38. class Test extends Simulation {
 val httpConf = http.baseURL("http://neo-database:7474")
 
 val test = scenario("GetGraph")
 .exec(
 http("execute_query")
 .post("/extension/query/execute")
 .body(StringBody("MATCH (root)-[:HAS*]->(child)"))
 .check(status.is(200))
 .check(jsonPath("$.results").count.is(100))
 )
 
 setUp(
 test.inject(
 rampUsersPerSec(0) to (1000) during (60 seconds)
 )
 ).protocols(httpConf)
 }
  39. 39. http("execute_query")
 .post( "/extension/query/execute" )
 .body(StringBody( "MATCH (root)-[:HAS*]->(child)" ))
 .check( status.is(200) )
 .check( jsonPath("$.results").count.is(100) ) 1 2 3 4
  40. 40. rampUsersPerSec(0) to (1000) during (60 seconds)
  41. 41. Requests/Second 0 150 300 450 600 Seconds 0 10 20 30 40 50 60
  42. 42. When request/second goes up And some threshold reached Then we receive Timeout error
  43. 43. Everything is ok? Maybe we can do higher load? How to spot the problem?
  44. 44. Drop all non-essential parts
  45. 45. Client LB DB1 DB2 DB3 - our extension
  46. 46. 0 250 500 750 1000 0 10 20 30 40 50 60
  47. 47. Client - Server communication problems
  48. 48. • Incorrect server setup • Unconfigured networking • Low max open connection limit
  49. 49. Learned - Performance testing should be done - Test results should be interpreted properly - Test results should be verified in different environments
  50. 50. We need to test different queries Feeders!
  51. 51. val feeder = Array(
 Map("query" -> "..."),
 Map("query" -> "..."),
 Map("query" -> "...")
 ) .queue .random .circular
  52. 52. 
 val test = scenario(“GetGraph") .feed(feeder)
 .exec(http("execute_query")
 .post("/extension/query/execute")
 .body(StringBody("${query}"))
 .check(status.is(200))
 .check(jsonPath("$.results").count.is(100))
 )
  53. 53. CSV JSON JDBC Sitemap Redis Custom http://gatling.io/docs/2.1.4/session/feeder.html
  54. 54. csv("data.csv").random
  55. 55. Our own feeder - Custom feeder - Lazy loads data - Performant
  56. 56. Dynamic user load? http://gatling.io/docs/2.1.4/general/simulation_setup.html
  57. 57. test.inject(
 nothingFor(5 seconds), atOnceUsers(10),
 rampUsersPerSec(10) to (100) during (20 seconds),
 constantUsersPerSec(100) during (40 seconds),
 rampUsersPerSec(100) to (500) during (20 second),
 constantUsersPerSec(100) during (60 seconds)
 )
  58. 58. Checks http://gatling.io/docs/2.1.4/http/http_check.html
  59. 59. - status - currentLocation - header - regex - xpath - jsonPath
  60. 60. regex("Invalid Page title").notExists
 status.is(200)
 jsonPath("$.posts").exists
 regex("""<div class="article">""").count.is(10)
  61. 61. Realtime monitoring http://gatling.io/docs/2.1.4/realtime_monitoring/index.html Execution progress visual feedback
  62. 62. Graphite (InfluxDB) + Grafana
  63. 63. Recorder http://gatling.io/docs/2.1.4/http/recorder.html
  64. 64. HTTP http://gatling.io/docs/2.1.4/http/recorder.html - HTTP Protocol - SSL - WebSocket - SSE
  65. 65. Jenkins integration https://github.com/jenkinsci/gatling-plugin
  66. 66. - Any IDE with Scala support is OK - Intellij IDEA - Eclipse (Scala IDE) - Netbeans
  67. 67. Our use cases
  68. 68. GET /api/node/1 POST /api/node UPDATE /api/node Basic API tests
  69. 69. - Generate background load - Make stability tests - Cluster communications - Load balancer setup - Spikes Load generator
  70. 70. - Simulate significant write load - Check how database reacts Data import
  71. 71. Easy Fun Performant

×