{"id":22447,"date":"2015-07-15T22:14:55","date_gmt":"2015-07-15T16:44:55","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=22447"},"modified":"2015-09-14T05:36:55","modified_gmt":"2015-09-14T00:06:55","slug":"master-slave-load-testing-using-aws-ec2-spot-instances","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/master-slave-load-testing-using-aws-ec2-spot-instances\/","title":{"rendered":"MASTER-SLAVE LOAD TESTING USING AWS EC2 SPOT INSTANCES"},"content":{"rendered":"<p>Load testing using JMeter from a single server generally yields the inaccurate result which doesn\u2019t meet the real-time scenario. When <a title=\"AWS Load Testing Services\" href=\"http:\/\/www.tothenew.com\/devops-automation-consulting\">performing load test from a single server<\/a>, there are some network bottlenecks which restrict JMeter to perform an accurate load test. If the number of users exceeds a limit, the network starts getting choked up leading to an incorrect result. It is always better to perform load test from different sites by sending concurrent users to your application which not only brings the level of accuracy to your load test but also give flexibility to check the performance of your web application in real time scenario.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Use case<\/b><\/p>\n<p>When we <a title=\"Case Study of AWS Load Testing\" href=\"http:\/\/www.tothenew.com\/devops-automation-consulting\">perform load test using EC2 servers<\/a>, we need to pay the full hour cost of the servers in spite of knowing that our load test will take less than an hour. When it comes to the master-slave setup of load testing, you might be needing 5-10 slave servers to perform an efficient load test. This problem can be solved by using the spot instances which can be available to you in 60-70% lesser cost than a previous one. Spot instances in this scenario will fit best in the picture because it doesn\u2019t matter if one of your slave instances got terminated due to high pricing, you can start your load test again with an ease. In this blog, I will be demonstrating how we can perform distributed load testing using master-slave setup in the same subnet of a VPC.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Master-Slave Jmeter Load Testing<\/b><\/p>\n<p>In Master-Slave JMeter load testing, one instance behaves like a master (generally a small-sized \u00a0instance) and multiple high-performance servers behave like slave servers. Slave servers actually perform the load test by sending requests on to the web application. The master server triggers the load test job and gives aggregated output in XML format which can further be converted into HTML format using Apache Ant tool.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Below is a bash script which will set up the master-slave configuration using spot- instances in a single public subnet.<\/b><\/p>\n<p><strong>Prerequisites:-<br \/>\n<\/strong>1. Load testing \u00a0JMX file<br \/>\n2. Apache Ant configured Master Server.<br \/>\n3. AWS-CLI<br \/>\n4. A build.xml for Apache Ant, required to present in the target directory of JMeter to view the result in a web browser after converting the result from XML to HTML.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Script Overview:-<\/b><\/p>\n<p>The script will perform following tasks step by step after being run from master JMeter server:-<\/p>\n<ol>\n<li>Choosing the number and type of slave servers.<\/li>\n<li>Bidding of slave servers by showing you the last hour pricing of the instances in all the Availability zones.<\/li>\n<li>Configuring JMeter on slave servers and preparing them for ready to use.<\/li>\n<li>Performing load test in a master-slave configuration.<\/li>\n<li>Giving XML output of the load test.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong> <b>Below is a script named \u201cuser_data_for_loadtesting.sh\u201d which will be passed as a user data to the slave servers when the spot requests will be accepted. The script will install JMeter in the slave servers and make them ready to use by running the script JMeter server.<\/b><\/strong><\/p>\n<p>[js]<br \/>\n#!\/bin\/bash<br \/>\n    \tsudo apt-get update<br \/>\n    \tsudo apt-get install jmeter -y<br \/>\n\t\tsudo sed -i &#8216;s\/remote_hosts=127\/#remote_hosts=127\/&#8217; \/usr\/share\/jmeter\/bin\/jmeter.properties<br \/>\n\t\tsudo \/usr\/share\/jmeter\/bin\/jmeter-server<br \/>\n[\/js]<\/p>\n<p><b> Below is the main script named \u201cperform_load_test.sh\u201d to perform the whole task.<\/b><\/p>\n<p>[js]<br \/>\n#!\/bin\/bash<br \/>\n        current_date=`date +%Y-%m-%dT%H:%M:%S`<br \/>\n        hour_ago_date=$(date +%Y-%m-%dT%H:%M:%S -d &quot;1hour ago&quot;)<br \/>\n        echo &quot;= + = + = + = +WELCOME TO AUTOMATED LOAD  TEST USING SPOT INSTANCES= + = + = +&quot;<br \/>\n        echo &quot;choose instance type:&quot;<br \/>\n        echo &quot;1.m3.medium&quot;<br \/>\n        echo &quot;2.m3.large&quot;<br \/>\n        echo &quot;enter choice:&quot;<br \/>\n        read ch<br \/>\n        case $ch in<br \/>\n                1) instance_type=m3.medium;;<br \/>\n                2) instance_type=m3.large;;<br \/>\n                *) invalid option;;<br \/>\n        esac<\/p>\n<p>        echo &quot;SPOT PRICE HISTORY FOR $instance_type IN LAST HOUR IS :- &quot;<br \/>\n        aws ec2 describe-spot-price-history &#8211;region us-east-1 &#8211;instance-types m3.medium &#8211;filters Name=&quot;product-description&quot;,Values=&quot;Linux\/UNIX&quot; &#8211;start-time $hour_ago_date &#8211;end-time $current_date &#8211;query &#8216;SpotPriceHistory[].[AvailabilityZone,SpotPrice]&#8217; &#8211;output text | tail -n 4<\/p>\n<p>        echo &quot;enter your spot price::&quot;<br \/>\n        read price<br \/>\n#Here is a need to encode the userdata script in base64 format to pass it as a user data.<\/p>\n<p>        userdata_encoded_slave=&quot;$(cat ~\/user_data_for_loadtesting.sh | base64 -w 0)&quot;<\/p>\n<p>        echo &quot;enter no. of slave instances required:: &quot;<br \/>\n        read number<br \/>\n        req_id=($(aws ec2 request-spot-instances  &#8211;region us-east-1 &#8211;spot-price $price  &#8211;launch-specification &quot;{ \\&quot;KeyName\\&quot;: \\&quot;kew\\&quot;, \\&quot;ImageId\\&quot;: \\&quot;ami-d05e75b8\\&quot; , \\&quot;InstanceType\\&quot;: \\&quot;m3.medium\\&quot; , \\&quot;UserData\\&quot;: \\&quot;$userdata_encoded_slave\\&quot; , \\&quot;SecurityGroupIds\\&quot;: [\\&quot;sg-8b451aef\\&quot;] }&quot;  &#8211;query &#8216;SpotInstanceRequests[].SpotInstanceRequestId&#8217; &#8211;output text &#8211;instance-count $number))<\/p>\n<p>        for r in &quot;${req_id[@]}&quot;<br \/>\n                do<br \/>\n                        aws ec2 describe-spot-instance-requests &#8211;spot-instance-request-ids $r &#8211;query &#8216;SpotInstanceRequests[].[SpotInstanceRequestId,State]&#8217; &#8211;output text | grep active<br \/>\n                        status=$?<br \/>\n                        while [ $status -ne 0 ]<br \/>\n                                do<br \/>\n                                        echo &quot;Checking for approval..Please wait&quot;<br \/>\n                                        sleep 8<br \/>\n                                        aws ec2 describe-spot-instance-requests &#8211;spot-instance-request-ids $req_id &#8211;query &#8216;SpotInstanceRequests[].[SpotInstanceRequestId,State]&#8217; &#8211;output text | grep active<br \/>\n                                        status=$?<br \/>\n                                done<\/p>\n<p>                        echo &quot;************! ! ! ! ! ! CONGRATULATIONS !!!!&#8230;.YOUR REQUEST HAS BEEN ACCEPTED !!!!!!!!*************************&quot;<\/p>\n<p>                        inst_id=`aws ec2 describe-spot-instance-requests &#8211;spot-instance-request-ids $r &#8211;query &#8216;SpotInstanceRequests[].InstanceId&#8217; &#8211;output text`<\/p>\n<p>                        ip=`aws ec2 describe-instances &#8211;instance-ids $inst_id  &#8211;query &#8216;Reservations[].Instances[].NetworkInterfaces[].Association[].PublicIp[]&#8217; &#8211;output text`<\/p>\n<p>                        echo &quot;The IP of allocated instance is :- $ip&quot;<br \/>\n                        r_ips=$r_ips,$ip   #formatting for jmeter command to pass remote IPs<br \/>\n                done<br \/>\n        remote_ips=`echo $r_ips | sed -e &#8216;s\/,\/\/&#8217;`<br \/>\n        sudo sed -i &#8216;s\/remote_hosts=127\/#remote_hosts=127\/&#8217; \/usr\/share\/jmeter\/bin\/jmeter.properties<br \/>\n        echo &quot;Performing load testing &#8230;&#8230;..Please wait&quot;<br \/>\n        echo &quot;Initializing Remote host..Please wait..&quot;<br \/>\n        sleep 210<br \/>\n      #to perform load test in master slave, the command is<br \/>\n      #jmeter -n -t &lt;jmx file&gt; -l &lt;result.xml&gt; -R xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx  (remote hosts)<br \/>\n       jmeter -n -t \/home\/ubuntu\/&lt;jmx-file.jmx&gt; -l \/home\/ubuntu\/result.xml -R $remote_ips<br \/>\n[\/js]<\/p>\n<p>In the end, you will get an XML file named result.xml which can easily be converted in HTML format using Ant Apache tool or some other tool.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Load testing using JMeter from a single server generally yields the inaccurate result which doesn\u2019t meet the real-time scenario. When performing load test from a single server, there are some network bottlenecks which restrict JMeter to perform an accurate load test. If the number of users exceeds a limit, the network starts getting choked up [&hellip;]<\/p>\n","protected":false},"author":170,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":19},"categories":[1174],"tags":[1950,1952,696,1948,1951,1949],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/22447"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/170"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=22447"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/22447\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=22447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=22447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=22447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}