I'm trying to send a large number of queries to my server. When I open a certain website (with certain parameters), it sends a query to my server, and computation is done on my server.
Right now I'm opening the website repeatedly using curl, but when I do that, the website contents are downloaded to my computer, which takes a long time and is not necessary. I was wondering how I could either open the website without using curl, or use curl without actually downloading the webpage.
Do the requests in parallel, like this:
#!/bin/bash
url="http://your.server.com/path/to/page"
for i in {1..1000} ; do
# Start curl in background, throw away results
curl -s "$url" > /dev/null &
# Probably sleep a bit (randomize if you want)
sleep 0.1 # Yes, GNU sleep can sleep less than a second!
done
# Wait for background workers to finish
wait
curl still downloads the contents to your computer, but basically a test where the client does not downloads the content would not be very realistic.
Obviously the above solution is limited by the network bandwith of the test server - which is, usually worse than the bandwith of the web server. For realistic bandwith tests you would need to use multiple test servers.
However, especially when it comes to dynamic web pages not the bandwith might be the bottleneck, but the memory or CPU. For such stress tests, a single test machine might be enough.
Related
In my laravel application, I am making a HTTP request to a remote server using guzzle library . However large time is required for data to reach local host.
Here is the resposne I get on browser ,
However if I run command ping server_IP I get roughly 175ms as average transmission time .
I also monitored my CPU usage after making requests in infinte loop, however I couldn't find much usage .
I also tried hosting my laravel application on nginx server, but I still observe around 1-1.1 seconds overhead .
What could be causing this delay and how can I reduce it ?
There are few potential reasons.
Laravel is not the fastest framework. There are few hundred of files which need to be loaded on every single request. If you server doesn't have a SSD drive your performance will be terrible. I'd recommend to create a RAMDISK and serve the files from there.
Network latency. Open up wireshark and look at all the requests that need to be done. All them impact negatively the performance and some of them you cannot get around (DNS,...). Try to combine the CSS and JS files so that the number of requests is minimised.
Database connection on server side takes long time to setup, retrieves lots of data,...
Bear in mind that in most situations the latency is due to IO constraints rather than CPU usage. Moreover in test/preproduction environments where the number of requests per second that the server gets rounds to 0.
I have set up a test plan using Apache JMeter, but when testing a remote server I am seeing much slower times than it takes the browser to run the same test, it's on order of 5-10x slower. For example chrome takes about 300ms to load a simple static page with some embedded assets while jmeter reports 2000+ms for the same page from the same machine.
I've tried tweaking the thread count to make sure this is not the bottleneck as well as not too much load slowing down the server, but nothing seems to change these slow numbers.
What else can I look at to get more realistic response times out of this tool?
I figured this one out, the issue was that "Retrieve all embedded resources" was checked, which I want, but I was also not using the "concurrent pool size" option, so it was cycling through each of the ~10 embedded HTTP requests on the page serially and reporting slow overall load times. Checking this and adding a realistic browser concurrency number (Chrome uses 6 these days so that's what I went with: http://sgdev-blog.blogspot.com/2014/01/maximum-concurrent-connection-to-same.html)
give me numbers that are very close to real browser testing.
Make sure you add HTTP Cache Manager as browsers download embedded stuff like images, scripts, styles, etc. but do it only once, on subsequent requests aforementioned resources are being returned from browser's cache, no actual request is being made.
See How to make JMeter behave more like a real browser guide for other recommendations on how to make your JMeter test more realistic.
I have a need to convert some of my perl CGI-scripts to binaries.
But when I have a script of 100kb converted into binary it becomes about 2-3Mb. This is understood why, as compiler has to pack inside all the needed tools to execute the script.
The question is about the time of pages loading on the server, when they are binary. Say, if I have a binary perl-script "script", that answers on ajax requests and that binary weights about 3mb, will it reflect on AJAX requests? If, say, some users have low connection, will they wait for ages until all these 3Mb will be transferred? Or, the server WON'T send all the 3mb to a user, but just an answer (short XML/JSON whatsoever)?
Another case is when I have HTML page, that is generated by this binary perl-script on the server. User addresses his browser to the script, that weights 3Mb and after he has to get an HTML page. Will the user wait again, until the whole script is been loaded (every single byte form those 3Mb), or just wait the time that is needed to load EXACTLY the HTML page (say, 70Kb), and the rest mass will be run on the server-side only and won't make the user to wait for it?
Thanks!
Or, the server WON'T send all the 3mb to a user, but just an answer (short XML/JSON whatsoever)?
This.
The server executes the program. It sends the output of the program to the client.
There might be an impact on performance by bundling the script up (and it will probably be a negative one) but that has to do with how long it takes the server to run the program and nothing to do with how long it takes to send data back to the client over the network.
Wrapping/Packaging a perl script into a binary can be useful for ease of transport or installation. Some folks even use it as a (trivial) form of obfuscation. But in the end, the act of "Unpacking" the binary into usable components at the beginning of every CGI call will actually slow you down.
If you wish to improve performance in a CGI situation, you should seriously consider techniques that make your script persistent to eliminate startup time. mod_perl is an older solution to this problem. More modern solutions include FCGI or wrapping your script into it's own mini web server.
Now if you are delivering the script to a customer and a PHB requires wrapping for obfuscation purposes, then be comforted that the startup performance hit only occurs once if you write your script to be persistent.
I want to start testing my server with a couple of clients before moving onto higher numbers.
The current plan right now is just to run tests to check/test latency by writing a script that takes in X amount of seconds that will determine how long the test runs. The script will launch the server and clients. On their end the ping testing code is already in place.
My problem is that while the server is easy to just launch it via a bash script, I don't know any easy way to also launch Chrome and have it go to the webpage. (the client)
Hoping this is an easy script, my scripting experience is limited :]
Chrome will accept URL's on its command-line, like so:
chrome http://www.google.com/
i am curious if there is a way of monitoring the request duration time on an iis server. Personally I have came up with a solution but it's really resource intensive and that is why i'm asking the question, just to gather more opinions.
My plan is to extract the duration time of each request and send it to graphite so as to have a real time overview of the performance of the webserver. The idea i've came up with is to use poweshell with its webadministration module. And if you run get-item IIS:\AppPools\DefaultAppPool | Get-WebRequest for example you get all the requests on that app pool with a lot of info including the time info.
The thing is that i should have a script which runs every 100 ms to get all requests and that is kinda wasteful. Is there a way to tell iis to put the request duration time(in miliseconds) in the logs? Because then it would be much easier to get the information I need.
I don't know if there is such a feature on IIS, but I've done the same (sending iis page times to graphite) by using a reverse proxy between internet and the iis server, like nginx.
The proxy module from nginx allow you to log on each request the time the backend took to produce the page.
Also, having a proxy like nginx in fron of an IIS could be very helpful if you have to deal with visits with slow connections, nginx will store the reply from backend, drop backend connection and wait until visitor gets all the content. Highly recommended.
In case you go this route, you should use logster (also from etsy guys) or logstash to parse nginx logs each period of time you want (likely every minute).
Seems that there is a feature that logs requests based on a regex, and it's called Advanced Logging Module. You can specify from a number of fields what you want to get loged and it's W3C compliant. In my case i had time take as a filed which can be specified and that was what i was looking for. After that i written a script in powershell which parses the logs and gets the information i need, constructs a metric and sends it to statsd which in term sends it to powershell.
The method i chose for the log parsing was the following: in the script i used get-content comandlet from powershell to gather all the logs in one file(yes iis breaks the logs in multiple files, and i'm guessing the number of logs is dependent on the number of your working processes but i'm not sure). This was the first iteration in a second iteration i gather all the logs in another file and make a diff between the first file and the latter and only the difference gets processed.
I chose this method because it's i thought it wold be better to have the minimum regex processing. The next step is erasing the first file of accumulated logs and moving the second one in pace of the first that was erased and running the script again, so to have always a method of comparison. Also the log rollover is at one hour, after which the logs are erased.