Top Banner
Load Testing with Jason Lotito “Guaranteed to be the best talk on load testing with PHP @ MidwestPHP 2016 during that time slot in that room with me as the speaker"
90

Load Testing with PHP and RedLine13

Apr 15, 2017

Download

Software

Jason Lotito
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Load Testing with PHP and RedLine13

Load Testingwith Jason Lotito

“Guaranteed to be the best talk on load testing with PHP @ MidwestPHP 2016 during that time

slot in that room with me as the speaker"

Page 2: Load Testing with PHP and RedLine13

Jason Lotito

• DevOps Lead Architect

• MeetMe.com

• @jasonlotito

• jasonlotito.com

[email protected]

Page 3: Load Testing with PHP and RedLine13

Lorem Ipsum Dolor

meetme.com/apps/careers

Page 4: Load Testing with PHP and RedLine13

Load TestingNot Unit Testing, Integration Testing, Acceptance Testings, manual Testing, or Standardized Testing

Page 5: Load Testing with PHP and RedLine13

Jason LotitoLoad test, or your users will do it for you.

Page 6: Load Testing with PHP and RedLine13

Load test, or your users will do it for you.

Your Servers

Page 7: Load Testing with PHP and RedLine13

Load test, or your users will do it for you.

And if they do, you won’t have any users.

Page 8: Load Testing with PHP and RedLine13

You can use load testing to practice dealing with lots of requests

Page 9: Load Testing with PHP and RedLine13

What is Load Testing?

Page 10: Load Testing with PHP and RedLine13

Load Testing

• Putting demand on a system

• Determine behavior under load

• Determine maximum operating capacity

• Discover Bottlenecks

• Determining steps to increase operating capacity

• Optimize for costs

Page 11: Load Testing with PHP and RedLine13

Other Load Testing Tools

• ApacheBench (ab)

• Apache JMeter

• siege

• BlazeMeter

• and many more…

Page 12: Load Testing with PHP and RedLine13

The Basics of Load Testing

Page 13: Load Testing with PHP and RedLine13

The Basics of Load Testing

Page 14: Load Testing with PHP and RedLine13

Why RedLine13?

• Simple, up and running in little time

• Freemium, free level you only pay AWS

• Scriptable (PHP, Node.js)

• AWS for Infinite Scalability™

• I know Rich, one of the founders

Page 15: Load Testing with PHP and RedLine13

RedLine13 has a bunch of features you can read about on the website. I’m really here to talk to you about the cool stuff I do with RedLine13.

Page 16: Load Testing with PHP and RedLine13
Page 17: Load Testing with PHP and RedLine13
Page 18: Load Testing with PHP and RedLine13
Page 19: Load Testing with PHP and RedLine13
Page 20: Load Testing with PHP and RedLine13

Let’s walk through a Custom Load Test

Page 21: Load Testing with PHP and RedLine13

CustomTest.phpThe class that actually runs the test.

Page 22: Load Testing with PHP and RedLine13

In our example, we’ll use sleep to simulate performing actions such as

making HTTP requests to an API

Page 23: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

This is where your code goes

Page 24: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

Page 25: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

Page 26: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

Page 27: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

Page 28: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

Page 29: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

Start Time

Start/End Time Difference

Page 30: Load Testing with PHP and RedLine13

<?phprequire_once( 'LoadTestingTest.class.php' ); class CustomTest extends LoadTestingTest{ public function startTest() { for ( $x = 1; $x <= 100; $x++ ) { $startTime = microtime(true); sleep( mt_rand( 2, 5 ) ); $diff = microtime( true ) - $startTime; recordPageTime( $startTime, $diff ); recordURLPageLoad( $x, $startTime, $diff ); } return true; } }

CustomTest.php

URL/String

Page 31: Load Testing with PHP and RedLine13

These next two files help us test locally

Page 32: Load Testing with PHP and RedLine13

redline.phpMock Redline functions to

test load test locally

Page 33: Load Testing with PHP and RedLine13

<?php/** * @return bool */function isRedlineVerbose(){ return (int) getenv( 'REDLINE_VERBOSE' ) === 1; } /** * @param int $timestamp * @param int $elapsedTime */function recordPageTime( $timestamp, $elapsedTime ) { isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" ); } /** * @param string $url

redline.php

Page 34: Load Testing with PHP and RedLine13

<?php/** * @return bool */function isRedlineVerbose(){ return (int) getenv( 'REDLINE_VERBOSE' ) === 1; } /** * @param int $timestamp * @param int $elapsedTime */function recordPageTime( $timestamp, $elapsedTime ) { isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" ); } /** * @param string $url

redline.php

Page 35: Load Testing with PHP and RedLine13

<?php/** * @return bool */function isRedlineVerbose(){ return (int) getenv( 'REDLINE_VERBOSE' ) === 1; } /** * @param int $timestamp * @param int $elapsedTime */function recordPageTime( $timestamp, $elapsedTime ) { isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" ); } /** * @param string $url * @param int $timestamp * @param int $elapsedTime */function recordURLPageLoad( $url, $timestamp, $elapsedTime ) { output( "$url -> $elapsedTime seconds" ); }

redline.php

Page 36: Load Testing with PHP and RedLine13

* @param int $timestamp * @param int $elapsedTime */function recordPageTime( $timestamp, $elapsedTime ) { isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" ); } /** * @param string $url * @param int $timestamp * @param int $elapsedTime */function recordURLPageLoad( $url, $timestamp, $elapsedTime ) { output( "$url -> $elapsedTime seconds" ); } /** * @param int $kilobytes */function recordDownloadSize( $kilobytes ) { isRedlineVerbose() && output( sprintf( "Download Size: %dkb", $kilobytes ) ); } /**

redline.php

Page 37: Load Testing with PHP and RedLine13

* @param string $url * @param int $timestamp * @param int $elapsedTime */function recordURLPageLoad( $url, $timestamp, $elapsedTime ) { output( "$url -> $elapsedTime seconds" ); } /** * @param int $kilobytes */function recordDownloadSize( $kilobytes ) { isRedlineVerbose() && output( sprintf( "Download Size: %dkb", $kilobytes ) ); } /** * @param string $error */function recordError( $error ) { output( "Error: $error" ); } /** * @param string $msg * @return bool

redline.php

Page 38: Load Testing with PHP and RedLine13

/** * @param int $kilobytes */function recordDownloadSize( $kilobytes ) { isRedlineVerbose() && output( sprintf( "Download Size: %dkb", $kilobytes ) ); } /** * @param string $error */function recordError( $error ) { output( "Error: $error" ); } /** * @param string $msg * @return bool */function output( $msg ) { echo sprintf( "[%s] %s]\n", getmypid(), $msg ); return true; }

redline.php

Page 39: Load Testing with PHP and RedLine13

$kilobytes ) ); } /** * @param string $error */function recordError( $error ) { output( "Error: $error" ); } /** * @param string $msg * @return bool */function output( $msg ) { echo sprintf( "[%s] %s]\n", getmypid(), $msg ); return true; }

redline.php

Page 40: Load Testing with PHP and RedLine13

run.phpThe script we create to

test CustomTest.php locally

Page 41: Load Testing with PHP and RedLine13

<?phprequire_once('redline.php'); require_once('CustomTest.php'); $customTest = new CustomTest(1, mt_rand(1000000,9999999)); $customTest->startTest();

run.php

Page 42: Load Testing with PHP and RedLine13

<?phprequire_once('redline.php'); require_once('CustomTest.php'); $customTest = new CustomTest(1, mt_rand(1000000,9999999)); $customTest->startTest();

run.php

Page 43: Load Testing with PHP and RedLine13

<?phprequire_once('redline.php'); require_once('CustomTest.php'); $customTest = new CustomTest(1, mt_rand(1000000,9999999)); $customTest->startTest();

run.php

Page 44: Load Testing with PHP and RedLine13

<?phprequire_once('redline.php'); require_once('CustomTest.php'); $customTest = new CustomTest(1, mt_rand(1000000,9999999)); $customTest->startTest();

run.php

Instance Number

Page 45: Load Testing with PHP and RedLine13

<?phprequire_once('redline.php'); require_once('CustomTest.php'); $customTest = new CustomTest(1, mt_rand(1000000,9999999)); $customTest->startTest();

run.php

User Number

Random Number

Page 46: Load Testing with PHP and RedLine13

What does a result look like?

Page 47: Load Testing with PHP and RedLine13
Page 48: Load Testing with PHP and RedLine13
Page 49: Load Testing with PHP and RedLine13
Page 50: Load Testing with PHP and RedLine13
Page 51: Load Testing with PHP and RedLine13
Page 52: Load Testing with PHP and RedLine13
Page 53: Load Testing with PHP and RedLine13
Page 54: Load Testing with PHP and RedLine13
Page 55: Load Testing with PHP and RedLine13

You can use error reporting to simulate real time logging

Errors show up in real time, logs show up after the test is completed. Use error reports to let you

know if you should stop your load test.

Page 56: Load Testing with PHP and RedLine13

Sample App: Chat Service

Page 57: Load Testing with PHP and RedLine13

Sample App: Chat Service

• 1-on-1 Chat

• Group Chat

• Browse Chat Rooms

• Search for Chat Room Topics

Page 58: Load Testing with PHP and RedLine13

Why split 1-on-1 and group chat into separate tests?

Page 59: Load Testing with PHP and RedLine13

Multiple tests can be run at the same time.

Page 60: Load Testing with PHP and RedLine13

1-on-1

Group30-40%

60-70%30-40%

60-70% 60-70%30-40%

Time

Start at the same time

Increase group chat %

Could mean just more group chat or both more group and less 1-on-1

Revert to normal ratio

20:00 40:000:00

Page 61: Load Testing with PHP and RedLine13

1-on-1

Group30-40%

60-70%30-40%

60-70% 60-70%30-40%

Time

Could be done in your script or in RedLine13

Page 62: Load Testing with PHP and RedLine13

How?

• Start 4 tests:

• For both group and 1-on-1:

• 350 users

• 300 users

Page 63: Load Testing with PHP and RedLine13

1-on-1

Group350

350+300350

350+300 350350

Time

300 test sleeps for 20 minutes

After 20 minutes, it stops.

Page 64: Load Testing with PHP and RedLine13

Or, instead of timers, just do it manually.

Usually the easiest on the day of.

Page 65: Load Testing with PHP and RedLine13

The point is, you can adjust your load test as needed.

Page 66: Load Testing with PHP and RedLine13

Performing Load Tests

Page 67: Load Testing with PHP and RedLine13

Things You Need

• Production-level systems to test against

• Monitoring

• Automated systems to deploy changes

• Dedicated people

• A time to test (load testing day!)

Page 68: Load Testing with PHP and RedLine13

Things You Need

• Goals, such as

• 500 requests per second

• 90th percentile @ 50ms

Page 69: Load Testing with PHP and RedLine13

Planning the Load Test

• Start at what you expect normal traffic to be

• 500rps

• Start a second test that is just the burst traffic

• 900rps

• Ramps up over 20 mins

• Lasts 40 mins at peak

• Ramps down over 20 mins

Page 70: Load Testing with PHP and RedLine13

Learning

• Is proper monitoring setup?

• Is a scaling plan in place? Can you scale?

• What happens to the app under load?

• What slows down first?

• Are things alerting as expected?

Page 71: Load Testing with PHP and RedLine13

As Load Tester, you are responsible for…

• Ensuring those involved with the system under test are aware and available

• Putting the system under test under load

• Completely destroying the system under load

• Providing a clear and concise write up of exactly what occurred

• Take charge! It’s fun!

Page 72: Load Testing with PHP and RedLine13

Reporting

Page 73: Load Testing with PHP and RedLine13

Reporting Results: Shortest Version

• 99% @ 59ms

Page 74: Load Testing with PHP and RedLine13

Reporting Results: Short Version

• Short version: During an hour starting with 0rps to 1400 rps in the first 10 minutes....

• ...when starting with 5 instances and scaling to 11 instances, the response times were: 50% 23ms, 75% 54ms, 95% 303ms, and 99% 1069ms.

• ...when starting with 11 instances, the response times were: 50% 16ms, 75% 24ms, 95% 45ms, and 99% 59ms.

Page 75: Load Testing with PHP and RedLine13

Reporting Results: Detailed Version

• Provide more information

• Results

• Story driven

• Have data supporting results prepared in case

• Account for changes such as auto-scaling

• With auto-scaling: 99% at 1069ms

• Without auto-scaling: 99% at 59ms

Page 76: Load Testing with PHP and RedLine13

Testing elasticsearch on c3.4xlarge

Detailed Reporting

Also included in this report was a link to the actual GitHub repository. Make sure you are keeping your load tests in version control!

Page 77: Load Testing with PHP and RedLine13

Tag your load test in gitAssociate the tag with a Load Test,

so you can replay any load test easily

Page 78: Load Testing with PHP and RedLine13

Lessons Learned

Page 79: Load Testing with PHP and RedLine13

Things to Keep In Mind

• Understand expected usage

• X% of users using the app while

• Y% are chatting with one another

• Users are logging in

• Creating accounts

• Backend systems

• Determine what’s important

Page 80: Load Testing with PHP and RedLine13

Things to Keep In Mind

• User input

• Random filters

• Weighted filters

• Cached results are expected

• Client constraints

Page 81: Load Testing with PHP and RedLine13

Things to Keep In Mind

• User flow through service

• Try to understand how users use the app

• Script should try to mimic

Page 82: Load Testing with PHP and RedLine13

Things to Keep In Mind

• Be careful about testing a single system

• System will have logging

• System will have backend services

• You’d be surprised what can cause failure

• A load test helps you learn before it’s in production

Page 83: Load Testing with PHP and RedLine13

Things to Keep In Mind

• User interaction

• MeetMe is social, so we’ve load tested chatting

• 1 test per 2 users, both chatting with one another

Page 84: Load Testing with PHP and RedLine13

Things to Keep In Mind

• Have developers available

• Better, have developers with you when load testing

Page 85: Load Testing with PHP and RedLine13

Things to Keep In Mind

• Find a problem, Fix it, Reroll app, Rerun test

• FFRR, or F2R2

• I just made that up

• Don’t use it.

Page 86: Load Testing with PHP and RedLine13

Things to Keep In Mind

• Start testing from your laptop

• Seriously, my MacBook Air could bring down Erlang services

• Database indexes are a thing

• While running a load test, you can run a single client form your laptop

Page 87: Load Testing with PHP and RedLine13

Things to Keep In Mind

• Someone should be testing the app/service as well

• Response times are only a number

• What does 50ms vs 300ms response times feel to the user

• What impact does 2x/3x/4x load have

• When auto-scaling, how does the client handle

Page 88: Load Testing with PHP and RedLine13

Things to Keep In Mind

• Review how the client is using the API

• Review how the API developer expects the client to use the API

• Model after what the client is doing

• Call out differences early

Page 89: Load Testing with PHP and RedLine13

LearnMost importantly…

Page 90: Load Testing with PHP and RedLine13

Thanks!

• @jasonlotito

• jasonlotito.com

[email protected]

• https://joind.in/talk/80910