From bee65534364065587bbaaf50f8d70ec82f5647fb Mon Sep 17 00:00:00 2001 From: Alexey Lavrenuke Date: Thu, 26 Jul 2012 18:33:13 +0400 Subject: [PATCH] README.md: a lot of edits --- README.md | 271 +++++++++++++++++++++++++++--------------------------- 1 file changed, 138 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index 6dfea89..4d9b273 100644 --- a/README.md +++ b/README.md @@ -4,46 +4,50 @@ Yandex.Tank is a console HTTP load testing instrument. ### Installation and Configuration -You should add proper repository to source.list on Debian-based environment. +You should add proper repositories on Debian-based environment. -For instance, on Lucid: +For instance, add following repos to ```sources.list``` on Lucid: ``` deb http://dist.yandex.ru/phantom lucid/amd64/ # on 32bit system use i386 instead of amd64 -#deb http://dist.yandex.ru/phantom lucid/i386/ +deb http://dist.yandex.ru/phantom lucid/i386/ deb http://dist.yandex.ru/phantom common/all/ ``` +Then update package list and install ```yandex-load-tank-base``` package: ```sudo apt-get update && sudo apt-get install yandex-load-tank-base``` -All needed packets will be installed. -For a mild load tests (less then 1000rps) an average laptop with 34/64bit Ubuntu (Lucid/Precise) will be sufficient. The tank could be easily used in virtual machine if queries aren't heavy and the load isn't big. -Otherwise it is recommended to request from your admin a physical server or a more capable virtual machine. +For mild load tests (less then 1000rps) an average laptop with 32/64bit Ubuntu (Lucid/Precise) would be sufficient. The tank could be easily used in virtual machine if queries aren't too heavy and load isn't too big. +Otherwise it is recommended to request a physical server or a more capable virtual machine from your admin. ### Firewall -Before test execution, please, check service availability. If service is running on server with IP x.x.x.x and listen TCP port zz, check instructions are: +Before test execution, please, check service availability. If service is running on server with IP x.x.x.x and listening for TCP port zz, try to connect to it with ```telnet``` like this: ```telnet x.x.x.x zz``` If everything OK, you'll see: -```$ telnet 23.23.23.23 80 +``` +$ telnet 23.23.23.23 80 Trying 23.23.23.23... Connected to 23.23.23.23. -Escape character is '^]'.``` - -Otherwise: -```$ telnet 8.8.8.8 80 +Escape character is '^]'. +``` +Otherwise if port is unreacheable: +``` +$ telnet 8.8.8.8 80 Trying 8.8.8.8... -telnet: Unable to connect to remote host: Connection timed out``` -(it's just example, programs nc/nmap/wget/curl could be used as well, but not ping!) +telnet: Unable to connect to remote host: Connection timed out +``` +(it's just an example, programs like ```nc/nmap/wget/curl``` could be used as well, but not ping!) ### Routing -OK, service is reachable, the next thing you should know is how far the Yandex.Tank is located from testing service. Heavy load can hang up, reboot switch, or at least lead to losses in network, so test results would be distorted. Be careful. Path estimation could be done by execution of 'tracepath' command or it analogs (tracert/traceroute) on server with Yandex.Tank. +OK, service is reachable, next thing you should know is how far Yandex.Tank is located from the service you'd like to test. Heavy load can make switch to be unresponsible or to reboot, or at least it may lead to network losses, so the test results would be distorted. Be careful. Path estimation could be done by execution of ```tracepath``` command or it analogs (```tracert/traceroute```) on Yandex.Tank machine: -```$ tracepath 23.23.23.24 +``` +$ tracepath 23.23.23.24 1: tank.example.com (23.23.23.23) 0.084ms pmtu 1450 1: target.load.example.com (23.23.23.24) 20.919ms reached 1: target.example.com (23.23.23.24) 0.128ms reached Resume: pmtu 1450 hops 1 back 64 ``` -hops 1 means that tank and target are in closest location. +Hops count = 1 means that tank and target are in closest location. ```$ tracepath 24.24.24.24 1: 1.example.com (124.24.24.24) 0.084ms pmtu 1450 @@ -56,10 +60,11 @@ hops 1 means that tank and target are in closest location. 6: 8.example.com (24.24.24.241) 0.525ms asymm 5 7: no reply ``` -In that example it is better to find another, more closer located tank. +In this example you'd better find another closer located tank. -### Tunning -For the top most performance the source server should have tuned system limits +### Tuning +To achieve the top most performance you should tune the source server system limits: +``` ulimit -n 30000 net.ipv4.tcp_max_tw_buckets = 65536 @@ -77,51 +82,53 @@ net.ipv4.tcp_max_orphans = 65536 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_low_latency = 1 net.ipv4.tcp_syncookies = 0 +``` ## Usage -So, you've installed Yandex.Tank to a proper server, close to target, access is permitted. +So, you've installed Yandex.Tank to a proper server, close to target, access is permitted and server is tuned. How to make a test? ### First Step -Create on server with Yandex.Tank file, e.g. load.conf +Create a file on a server with Yandex.Tank: -``` > load.conf``` -Write into it +**load.conf** ``` address=23.23.23.23:80 #Target's address and port . -load = #load scheme ```!!Attention: IP address allowed only, not FQDN!! +load = line(1, 100, 10m) #load scheme +``` +!!Attention: IP address allowed only, not FQDN!! Yandex.Tank have 3 primitives for describing load scheme: - 1. [step (a,b,step,dur)] #Makes stepped load, where a,b are start/end load values, step - increment value, dur - step duration. - 2. [line (a,b,dur)] #Makes linear load, where a,b are start/end load, dur - the time for linear load increase from a to b. - 3. [const (load,dur)] #Makes constant load. load - rps amount, dur - load duration. - [const (a/b,dur)] # Fractional load, a/b rps, where a >= 0, b > 0. - Note: - const(0, 10) - 0 rps for 10 seconds, in fact 10s pause in test + 1. ```step (a,b,step,dur)``` makes stepped load, where a,b are start/end load values, step - increment value, dur - step duration. + 2. ```line (a,b,dur)``` makes linear load, where a,b are start/end load, dur - the time for linear load increase from a to b. + 3. ```const (load,dur)``` makes constant load. load - rps amount, dur - load duration. +You can set fractional load like this: ```const (a/b,dur)``` -- a/b rps, where a >= 0, b > 0. +Note: ```const(0, 10)``` - 0 rps for 10 seconds, in fact 10s pause in a test. - step and line could be used with increasing and decreasing intensity: - step(25, 5, 5, 60) - stepped load from 25 to 5 rps, with 5 rps steps, step duration 60s. - step(5, 25, 5, 60) - stepped load from 5 to 25 rps, with 5 rps steps, step duration 60s - line(100, 1, 10m) - linear load from 100 to 1 rps, duration - 10 minutes - line(1, 100, 10m) - linear load from 1 to 100 rps, duration - 10 minutes +```step``` and ```line``` could be used with increasing and decreasing intensity: +```step(25, 5, 5, 60)``` - stepped load from 25 to 5 rps, with 5 rps steps, step duration 60s. +```step(5, 25, 5, 60)``` - stepped load from 5 to 25 rps, with 5 rps steps, step duration 60s +```line(100, 1, 10m)``` - linear load from 100 to 1 rps, duration - 10 minutes +```line(1, 100, 10m)``` - linear load from 1 to 100 rps, duration - 10 minutes - Time duration could be defined in second (without dimension), minutes (m) and hours (h). For example: 27h103m645 +Time duration could be defined in second (without dimension), minutes (m) and hours (h). For example: ```27h103m645``` For a test with constant load at 10rps for 10 minutes, load.conf should have next lines: ``` address=23.23.23.23:80 #Target's address and port load = const (10,10m) #Load scheme ``` -Voilà, Yandex.Tank setup is done +Voilà, Yandex.Tank setup is done. -### Requests prepairing -There are two ways of requests declaration -#### Urls listed in load.conf or in separate file (so called uri-style) +### Preparing requests +There are two ways to set up requests. +#### URI-style +URIs listed in load.conf or in a separate file. -##### Requests in load.conf +##### URIs in load.conf Update configuration file with HTTP headers and URIs: ``` -address=23.23.23.23:80 #Target's address and port -load = const (10,10m) #Load scheme +address=23.23.23.23:80 # Target's address and port +load = const (10,10m) # Load scheme # Headers and URIs for GET requests header_http = 1.1 header_connection = close @@ -131,11 +138,12 @@ uri = /buy uri = /sdfg?sdf=rwerf uri = /sdfbv/swdfvs/ssfsf ``` -Parameters **header_*** define headers values. - **uri** contain uri, which should be used for requests generation. +Parameters like ```header_``` define headers values. +```uri``` contains uri, which should be used for requests generation. -##### Requests in file -File ammo.txt with declared requests: +##### URIs in file +Create a file with declared requests: +**ammo.txt** ``` [Connection: close] [Host: target.example.com] @@ -146,17 +154,24 @@ File ammo.txt with declared requests: /buy/?rt=0&station_to=7&station_from=9 ``` -File begins with optional lines [...], containing headers which will be added to every request. After that section there is URI list. Every URI must be in a new line, with leading '/'. - -#### Request "as-is" in file -For more complex requests, like POST, you'll have to create special file. +File begins with optional lines [...], that contain headers which will be added to every request. After that section there is a list of URIs. Every URI must begin from a new line, with leading '/'. +#### Request-style +Full requests listed in a separate file. +For more complex requests, like POST, you'll have to create a special file. File format is: +``` [size_of_request] [tag]\n [body_request] \r\n +[size_of_request2] [tag]\n +[body_request2] +\r\n +``` +where size_of_request – request size in bytes. +'\r\n' symbols after body_requests are ignored and not sent anywhere, but it is required to include it in a file after each request. '\r' is also required. -<{**Example GET:** - +**sample GET requests** +``` 73 good GET / HTTP/1.0 Host: xxx.tanks.example.com @@ -171,11 +186,10 @@ User-Agent: xxx (shell 1) GET /ab ra HTTP/1.0 Host: xxx.tanks.example.com User-Agent: xxx (shell 1) - -... -}> -<{**Example POST:** -```904 +``` +**sample POST requests** +``` +904 POST /upload/2 HTTP/1.0 Content-Length: 801 Host: xxxxxxxxx.dev.example.com @@ -194,10 +208,11 @@ User-Agent: xxx (shell 1) ^.^........QMO.0^.++^zJw.ر^$^.^Ѣ.^V.J....vM.8r&.T+...{@pk%~C.G../z顲^.7....l...-.^W"cR..... .&^?u.U^^.^.....{^.^..8.^.^.I.EĂ.p...'^.3.Tq..@R8....RAiBU..1.Bd*".7+. -.Ol.j=^.3..n....wp..,Wg.y^.T..~^..``` -}> -<{**Example POST multipart:** -```533 +.Ol.j=^.3..n....wp..,Wg.y^.T..~^.. +``` +**sample POST multipart:** +``` +533 POST /updateShopStatus? HTTP/1.0 User-Agent: xxx/1.2.3 Host: xxxxxxxxx.dev.example.com @@ -219,34 +234,33 @@ Content-Disposition: form-data; name="wsw-fields" disable --AGHTUNG-- -Connection: Close``` -}> -size_of_request – request size in bytes, that amount of data will be send over network. '\r\n' symbols after body_requests are ignored and not sent anywhere. +Connection: Close +``` ### Run Test! -1. Uri are in load.conf +1. Request specs in load.conf ``` lunapark ``` -2. Uri are in ammo.txt +2. Request specs in ammo.txt ``` lunapark ammo.txt ``` + Yandex.Tank detects requests format and generates ultimate requests versions. -'lunapark' here - inherited name of Yandex.Tank. +```lunapark``` here is an executable file name of Yandex.Tank. If Yandex.Tank has been installed properly and configuration file is correct, the load will be given in next few seconds. ### Results -During test execution you are shown HTTP and net errors, answers time distribution, progressbar and other interesting data. -At the same time file phout.txt is being written, which could be analyzed later. +During test execution you'll see HTTP and net errors, answer times distribution, progressbar and other interesting data. +At the same time file ```phout.txt``` is being written, which could be analyzed later. ### Tags -Requests could be grouped and marked by some word named 'tag' -Example of file with requests and tags: +Requests could be grouped and marked by some tag. Example of file with requests and tags: ``` 73 good GET / HTTP/1.0 @@ -263,10 +277,11 @@ GET /ab ra HTTP/1.0 Host: xxx.tanks.example.com User-Agent: xxx (shell 1) ``` -RESTRICTION: latin letters allowed only. +'good', 'bad' and 'unknown' here are the tags. +**RESTRICTION: latin letters allowed only.** ### SSL -For SSL activation add 'ssl = 1' to load.conf. Don't forget to change port number to appropriate value. +To activate SSL add 'ssl = 1' to load.conf. Don't forget to change port number to appropriate value. Now, our basic config looks like that: ``` address=23.23.23.23:443 #Target's address and port @@ -274,18 +289,17 @@ load = const (10,10m) #Load scheme ssl=1 ``` ### Autostop -Autostop is ability to automatically halt test execution if some conditions are reached. - HTTP and Net codes conditions: - There is an option to define specific codes (404,503,100) as well as code groups (3xx, 5xx, xx). - Also you can define relative threshold (percent from the whole amount of answer per second) or absolute (amount of answers with specified code per second). - Examples: - [autostop = http(4xx,25%,10)] – stop test, if amount of 4xx http codes in every second of last 10s period exceeds 25% of answers (relative threshold) - [autostop = net(101,25,10)] – stop test, if amount of 101 net-codes in every second of last 10s period is more than 25 (absolute threshold) - [autostop = net(xx,25,10)] – stop test, if amount of non-zero net-codes in every second of last 10s period is more than 25 (absolute threshold) +Autostop is an ability to automatically halt test execution if some conditions are reached. +#### HTTP and Net codes conditions +There is an option to define specific codes (404,503,100) as well as code groups (3xx, 5xx, xx). Also you can define relative threshold (percent from the whole amount of answer per second) or absolute (amount of answers with specified code per second). +Examples: +```autostop = http(4xx,25%,10)``` – stop test, if amount of 4xx http codes in every second of last 10s period exceeds 25% of answers (relative threshold) +```autostop = net(101,25,10)``` – stop test, if amount of 101 net-codes in every second of last 10s period is more than 25 (absolute threshold) +```autostop = net(xx,25,10)``` – stop test, if amount of non-zero net-codes in every second of last 10s period is more than 25 (absolute threshold) - Average time conditions: - Example: - [autostop = time(1500,15)] – stop test, if average answer time exceeds 1500ms +#### Average time conditions +Example: +```autostop = time(1500,15)``` – stop test, if average answer time exceeds 1500ms So, if we want to stop test when all answers in 1 second period are 5xx, add autostop line to load.conf: ``` @@ -296,15 +310,16 @@ autostop = http(5xx,100%,1) ### Logging Looking into target's answers is quite useful in debugging. For doing that add 'writelog = 1' to load.conf. -ATTENTION: Writing answers on high load leads to intensive disk i/o usage and can affect test accuracy. +**ATTENTION: Writing answers on high load leads to intensive disk i/o usage and can affect test accuracy.** Log format: -<[ +``` + - + +``` Where metrics are: - size_in size_out response_time(interval_real) interval_event net_code - (request size, answer size, response time, time to wait for response from the server, answer network code) +```size_in size_out response_time(interval_real) interval_event net_code``` (request size, answer size, response time, time to wait for response from the server, answer network code) Example: ``` user@tank:~$ head answ_*.txt @@ -320,7 +335,7 @@ HTTP/1.1 200 OK Content-Type: application/javascript;charset=UTF-8 ``` -Current load.conf is: +For ```load.conf``` like this: ``` instances=10 address=23.23.23.23:443 #Target's address and port @@ -331,9 +346,8 @@ writelog=1 ``` ### Results in phout -phout.txt - is a phantom written per-request log. It could be used for separate analyze (Excel/gnuplot/etc) - -14th phantom writes next fields to phout.txt: time, tag, interval_real, connect_time, send_time, latency, receive_time, interval_event, size_out, size_in, net_code proto_code +phout.txt - is a per-request log. It could be used for service behaviour analysis (Excel/gnuplot/etc) +It has following fields: ```time, tag, interval_real, connect_time, send_time, latency, receive_time, interval_event, size_out, size_in, net_code proto_code``` Phout example: ``` @@ -349,71 +363,62 @@ Phout example: 1326453006.598 257 58 32 106 61 110 37 478 0 404 1326453006.602 315 59 27 160 69 161 37 478 0 404 1326453006.603 256 59 33 107 57 110 53 476 0 404 -1326453006.605 241 53 26 130 32 131 37 478 0 404``` +1326453006.605 241 53 26 130 32 131 37 478 0 404 +``` +**NOTE:** as Yandex.Tank uses phantom as an http load engine and this file is written by phantom, it contents depends on phantom version installed on your Yandex.Tank system. ### Graph and statistics -Under construction, not implemented yet +Use your favorite stats packet, R, for example. Internal stat and graphing tool is under construction. ### Custom timings -time_periods = 10 45 50 100 150 300 500 1s 1500 2s 3s 10s # the last value - 10s is considered as connect timeout. +You can set custom timings in ```load.conf``` with ```time_periods``` parameter like this: ``` instances=10 address=23.23.23.23:443 #Target's address and port load = const (10,10m) #Load scheme -ssl=1 -autostop = http(5xx,100%,1) -writelog=1 time_periods = 10 45 50 100 150 300 500 1s 1500 2s 3s 10s # the last value - 10s is considered as connect timeout. ``` -### Threads limit -instances=N limits number of connects/threads. +### Thread limit +```instances=N``` in ```load.conf``` limits number of simultanious connections (threads). Test with 10 threads: ``` instances=10 address=23.23.23.23:443 #Target's address and port load = const (10,10m) #Load scheme -ssl=1 -autostop = http(5xx,100%,1) ``` -### Threads manipulating -instances_schedule = # Test with active instances schedule will be performed if load scheme is not defined. Bear in mind that active instances number cannot be decreased and final number of them must be equal to general instances number. -load.conf example: -```instances=10 -instances_schedule = line(1,10,10m) -address=23.23.23.23:443 #Target's address and port -#load = const (10,10m) #Load scheme -ssl=1 -autostop = http(5xx,100%,1)``` - -### Custom stateless protocol -In necessity of testing stateless HTTP-like protocol, Yandex.Tank's HTTP parser could be switched off, providing ability to generate load with any data, receiving any answer in return. -To do that add 'tank_type = 2'. !!Indispensable condition: Connection close must be initiated by remote side!! +### Dynamic thread limit +```instances_schedule = ``` -- test with active instances schedule will be performed if load scheme is not defined. Bear in mind that active instances number cannot be decreased and final number of them must be equal to ```instances``` parameter value. load.conf example: ``` instances=10 +instances_schedule = line(1,10,10m) address=23.23.23.23:443 #Target's address and port +#load = const (10,10m) #Load scheme is excluded from this load.conf as we used instances_schedule parameter +``` + +### Custom stateless protocol +In necessity of testing stateless HTTP-like protocol, Yandex.Tank's HTTP parser could be switched off, providing ability to generate load with any data, receiving any answer in return. +To do that add ```tank_type = 2``` to ```load.conf```. +**Indispensable condition: Connection close must be initiated by remote side** +load.conf example: +``` +instances=10 +address=23.23.23.23:80 #Target's address and port load = const (10,10m) #Load scheme -ssl=1 -autostop = http(5xx,100%,1) -#tank_type=2 # Parameter Nonna is commented for compatibility reasons. +tank_type=2 # Parameter Nonna is commented for compatibility reasons. ``` ### Gatling -If server with installed Yandex.Tank have several IPs, they could be used to avoid outcome port shortage. -gatling_ip = 23.23.23.24 23.23.23.25 +If server with Yandex.Tank have several IPs, they may be used to avoid outcome port shortage. Use ```gatling_ip``` parameter for that. Load.conf: -```instances=10 -address=23.23.23.23:443 #Target's address and port -load = const (10,10m) #Load scheme -ssl=1 -autostop = http(5xx,100%,1) -writelog=1 -time_periods = 10 45 50 100 150 300 500 1s 1500 2s 3s 10s # the last value - 10s is considered as connect timeout. -#gatling_ip = 23.23.23.24 23.23.23.26 # Commented, ips are listed as example -#tank_type=2 # Parameter Nonna is commented for compatibility reasons. ``` -**exec with -g key** +instances=10 +address=23.23.23.23:80 #Target's address and port +load = const (10,10m) #Load scheme +gatling_ip = 23.23.23.24 23.23.23.26 +``` +**run lunapark with -g key** ### Sources Yandex.Tank sources ((https://github.com/yandex-load/yandex-tank here)).