{"id":111,"date":"2004-03-21T12:57:32","date_gmt":"2004-03-21T18:57:32","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=111"},"modified":"2004-03-21T12:57:32","modified_gmt":"2004-03-21T18:57:32","slug":"the-grinder","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/111","title":{"rendered":"The Grinder"},"content":{"rendered":"<p>I did some performance testing against a web application that I helped write this weekend.  I used <a href='http:\/\/sourceforge.net\/projects\/grinder\/'>The Grinder<\/a> and was quite happy with the beta version.  This lets you write scripts in <a href='http:\/\/www.jython.org'>Jython<\/a> and uses the quite nice <a href='http:\/\/www.innovation.ch\/java\/HTTPClient\/'>HTTPClient<\/a> library.  The Grinder, like most other performance tools, has an admin interface (the console) and a set up distributed agents that are given tasks and communicate results back via the network to the console.  I used the HTTP client, but it looks like you can &#8216;grind&#8217; anything you can talk to via java, from <a href='http:\/\/grinder.sourceforge.net\/g3\/script-gallery.html#jdbc'>databases<\/a> to <a href='http:\/\/grinder.sourceforge.net\/g3\/script-gallery.html#javamail'>email servers<\/a>.<\/p>\n<p>I did run into a few problems.  I&#8217;m using <a href='http:\/\/www.cygwin.com'>cygwin<\/a> on WinXP, and had some difficulties running java from the command line.  The fix was to use the cygpath command, like so:<\/p>\n<p><code>#!\/bin\/sh<br \/>\n# to start the agent<br \/>\nJAVA=\/cygdrive\/c\/j2sdk1.4.2_03\/bin\/java<br \/>\nCLASSPATH=`cygpath -p -w \/home\/Owner\/work\/grinder\/grinder-3.0-beta20\/lib\/grinder.jar:\\<br \/>\n\/home\/Owner\/work\/grinder\/grinder-3.0-beta20\/lib\/jakarta-oro-2.0.6.jar:\\<br \/>\n\/home\/Owner\/work\/grinder\/grinder-3.0-beta20\/lib\/jython.jar`<br \/>\n$JAVA -cp $CLASSPATH net.grinder.Grinder<br \/>\n<\/code><\/p>\n<p>The client application that I was testing doesn&#8217;t use cookies (it&#8217;s a J2ME application, and the <a href='http:\/\/www.jcp.org\/aboutJava\/communityprocess\/final\/jsr037\/'>MIDP spec<\/a> doesn&#8217;t support cookies <a href='http:\/\/www.javaworld.com\/javaworld\/jw-04-2002\/jw-0426-wireless.html'>out of the box<\/a>).  Or rather, it uses cookies, but only to grab the first one that the server sends, store it off, and then pass it back as a query parameter.  This type of configuration isn&#8217;t The Grinder&#8217;s sweet spot, and I had to do a bit of hacking to make sure the appropriate cookie value was sent with the appropriate client request.  It would have been nice to use <a href='http:\/\/www.innovation.ch\/java\/HTTPClient\/advanced_info.html#contexts'>contexts<\/a> but The Grinder wraps the HTTPConnection in its own class.  Apparently, if you are simulating use by a browser, cookies are apparently <a href='http:\/\/sourceforge.net\/mailarchive\/message.php?msg_id=6519315'>handled correctly<\/a>.  One gripe&#8211;there&#8217;s no javadoc for the main classes available on The Grinder&#8217;s <a href='http:\/\/grinder.sourceforge.net'>website<\/a>, so you have to grab the <a href='http:\/\/prdownloads.sourceforge.net\/grinder\/grinder-3.0-beta20-src.zip?download'>source<\/a> if you want to see interactions between pieces (for example, how <code>net.grinder.plugin.http.HTTPRequest<\/code> interacts with <code><a href='http:\/\/www.innovation.ch\/java\/HTTPClient\/api\/HTTPClient\/HTTPConnection.html'>HTTPClient.HTTPConnection<\/a><\/code>).<\/p>\n<p>I also mucked with some of the properties, primarily <a href='http:\/\/grinder.sourceforge.net\/g3\/getting-started.html#grinder.initialSleepTime'>initialSleepTime<\/a>. You&#8217;ll want to make sure that you read about these properties&#8211;I blithely uncommented what was in the sample grinder.properties and ended up with an obscene value for <a href='http:\/\/grinder.sourceforge.net\/g3\/getting-started.html#grinder.sleepTimeFactor'>grinder.sleepTimeFactor<\/a>.<\/p>\n<p>After all the setup, I was able to hammer our server.  I discovered two useful things: an error in our logout code, which threw exceptions around 10% of the time, and also discovered that our <a href='http:\/\/jakarta.apache.org\/tomcat\/tomcat-4.1-doc\/config\/coyote.html'>connection timeout <\/a> between Apache and Tomcat was set incorrectly.  Changing this from 0 to 1000 fixed the dreaded <code>SEVERE: All threads are busy, waiting. Please increase maxThreads or check the servlet status<\/code> error that I was getting.  In addition to these two useful bugs, by making some assumptions about how the application will be used, I was able to <a href='http:\/\/www.quotegarden.com\/statistics.html'>gimmick up<\/a> some interesting numbers about supportable users.<\/p>\n<p>I like The Grinder a fair bit.  It&#8217;s got a nice GUI.  It&#8217;s still under active development.  I&#8217;m a bit leery of using beta software (especially open source beta software), but a <a href='http:\/\/www.votations.com\/asp\/resultsview.asp?pollid=110588'>poll<\/a> on the homepage convinced me to try the beta.  By using this, I was also able to pick up snatches of <a href='http:\/\/www.python.org'>python<\/a> which is a new language to me (finally got to consult my long unused copy of <a href='http:\/\/www.oreilly.com\/catalog\/lpython\/'>Learning Python<\/a>).  I considered looking at <a href='http:\/\/jakarta.apache.org\/jmeter\/'>JMeter<\/a>, but The Grinder appears to be <a href='http:\/\/apache.mirrors.redwire.net\/jakarta\/jmeter\/binaries\/'>a bit more recently maintained<\/a>.  It&#8217;s no <a href='http:\/\/www-svca.mercuryinteractive.com\/products\/loadrunner\/'>LoadRunner<\/a>, but then again, it doesn&#8217;t <a href='http:\/\/grinder.sourceforge.net\/g3\/faq.html#grinder-vs-loadrunner'>pretend to be<\/a>.  All in all, if you&#8217;re in the market for a cheap, quick performance tool, The Grinder is worth a look.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I did some performance testing against a web application that I helped write this weekend. I used The Grinder and was quite happy with the beta version. This lets you [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6],"tags":[],"class_list":["post-111","post","type-post","status-publish","format-standard","hentry","category-java","category-programming"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/111","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=111"}],"version-history":[{"count":1,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/111\/revisions"}],"predecessor-version":[{"id":631,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/111\/revisions\/631"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}