<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Thinking Outloud</title>
	<atom:link href="http://thebull.macsimumweb.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://thebull.macsimumweb.com</link>
	<description>Thoughts on poker, programming and other stuff.</description>
	<pubDate>Wed, 05 Nov 2008 06:42:46 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>No surprise</title>
		<link>http://thebull.macsimumweb.com/no-surprise</link>
		<comments>http://thebull.macsimumweb.com/no-surprise#comments</comments>
		<pubDate>Wed, 05 Nov 2008 06:42:46 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[liberal]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/?p=271</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/no-surprise";</script>
New and Used Mac Minis available on MacMini.com
]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/no-surprise";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p><img src="http://thebull.macsimumweb.com/wp-content/upload/2008/11/no_surprise.jpg" alt="" title="no_surprise" width="470" height="138" class="alignnone size-full wp-image-272" />
<p>New and Used Mac Minis available on <a href="http://www.usedmacmini.com">MacMini.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/no-surprise/feed</wfw:commentRss>
		</item>
		<item>
		<title>Using Groovy for monitoring via JMX</title>
		<link>http://thebull.macsimumweb.com/using-groovy-for-monitoring-via-jmx</link>
		<comments>http://thebull.macsimumweb.com/using-groovy-for-monitoring-via-jmx#comments</comments>
		<pubDate>Tue, 04 Nov 2008 18:49:47 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[groovy]]></category>

		<category><![CDATA[jmx]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/?p=253</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/using-groovy-for-monitoring-via-jmx";</script>Where I work we had a desire to be able to monitor our application as well as various JVM stats. Currently we use a groovy script to scan the logs every 15 minutes and report on errors if a certain threshold is passed. In our case it is currently 100 errors in that time frame. [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/using-groovy-for-monitoring-via-jmx";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>Where I work we had a desire to be able to monitor our application as well as various JVM stats. Currently we use a groovy script to scan the logs every 15 minutes and report on errors if a certain threshold is passed. In our case it is currently 100 errors in that time frame. We also have a heartbeat monitor set up for the servers and we can see the load, session counts, etc. via a customized version of linux&#8217;s top.</p>
<p>However, we wanted to be able to see more information. Things like blocked threads, connection pool reaching saturation, spikes in thread creation, etc. Naturally JMX is the appropriate mechanism to achieve all of that, but we wanted a means to automate the process. To script it. </p>
<h3>Enter Groovy</h3>
<p>I had written a few groovy scripts already, such as the log scanner, so I figured why not use it for JMX stuff as well. While groovy has  GroovyMBean object, most of the work was done using the basic JMX api, which wasn&#8217;t too bad once you got the hang of it.</p>
<h3>The Basics</h3>
<p>The first thing to do of course is get a connection to the JMX server. In our case we use an array of URLs to connect to and pull the stats for each in turn.</p>
<p>Here is the connection part:<br />
<code><br />
import javax.management.ObjectName<br />
import javax.management.remote.JMXConnectorFactory as JmxFactory<br />
import javax.management.remote.JMXServiceURL as JmxUrl<br />
import javax.management.MBeanServerConnection<br />
import javax.management.Query</p>
<p>def serverUrls = ['array of connection urls here']</p>
<p>serverUrls.each { serverUrl-&gt;<br />
def matcher = serverUrl =~ /.*(web4\d).*/</p>
<p>def box = matcher[0][1]<br />
  new File(box + &#8216;_stats.txt&#8217;).withWriter { file-&gt;<br />
    def server = JmxFactory.connect(new JmxUrl(serverUrl)).mBeanServerConnection<br />
</code></p>
<p>Notice the regex and File object. In our case I&#8217;m taking the info and dumping it to a text file, one for each server, and another process reads that file and processes it. </p>
<h3>Monitoring Tomcat</h3>
<p>The first thing we wanted to do was look at tomcat itself. Namely how many threads are waiting, blocked and running. If there are any blocked threads, then we dump out the thread info for it. So first let us get the Tomcat JMX object:<br />
code><br />
    query = new ObjectName(&#8217;Catalina:type=Manager,path=/,host=XYZ&#8217;)<br />
    def attr = server.getAttribute(query,&#8221;activeSessions&#8221;)<br />
</code><br />
Naturally you would want to replace &#8220;XYZ&#8221; for your actual host name. From there, we can start extracting some information:</p>
<p><code><br />
file.writeLine '#'<br />
    file.writeLine '# Tomcat info'<br />
    file.writeLine '#'<br />
    file.writeLine('activeSessions=' + attr)<br />
    file.writeLine('expiredSessions=' + server.getAttribute(query,"expiredSessions") )<br />
    file.writeLine('maxActiveSessions=' + server.getAttribute(query,"maxActiveSessions") )<br />
</code></p>
<p>That takes care of some session stuff, now we dive into the threads. First we get a hold of the Threading JMX object and set up some variables.</p>
<pre>
def threadingObject = new ObjectName('java.lang:type=Threading')
def threadIds = server.getAttribute( threadingObject, 'AllThreadIds' )

def threadCount = 0
def blockedThreads = new ArrayList()
def waitingThreads = 0
def runningThreads = 0
def timedWaiting = 0
</pre>
<p>Now we loop through all of the thread ids and look specifically for the HTTP threads, which have a name like &#8220;http-8080-exec&#8221; or &#8220;http-8443-exec&#8221;:</p>
<pre>
def sig = ['long']
    threadIds.each { id->
      def params = new Object[1]
      params[0] = id.toLong()
      def thread =
        server.invoke( threadingObject, 'getThreadInfo',params, sig.toArray( new String[1]) )

      if( thread.get('threadName').matches("http-\\d\\d\\d\\d-e.*") ) {
        threadCount++
        if( thread.get('threadState') == 'TIMED_WAITING' )
          timedWaiting++
        else if( thread.get('threadState') == 'BLOCKED' )
          blockedThreads.add( thread.get('threadName') )
        else if( thread.get('threadState') == 'RUNNABLE' )
          runningThreads++
        else if( thread.get('threadState') =='WAITING' )
          waitingThreads++
      }
    }
</pre>
<p>Now we write out that info and if there were any blocked threads, we dump out the thread name. From that we can hook into the JVM via JConsole and examine the thread, look for deadlocks, etc. Of course we could probably dump out some of that stuff here too.</p>
<pre>
file.writeLine "HTTP Threads=" + threadCount
    file.writeLine "Waiting Threads=" + waitingThreads
    file.writeLine "Timed Waiting Threads=" + timedWaiting
    file.writeLine "Running threads=" + runningThreads
    file.writeLine "Blocked Thread Count=" + blockedThreads.size()

    if( blockedThreads.size() > 0 ) {
       file.write( "Blocked Threads=" )
       blockedThreads.each{ t->
         file.write t+','
       }
       file.writeLine ''
    }
</pre>
<p>Here we are looking at system level stuff such as the uptime:</p>
<pre>
//
// System stuff
//
file.writeLine '#'
file.writeLine '# System properties'
file.writeLine '#  - uptime is in milliseconds'
file.writeLine '# - ' + (server.getAttribute( new ObjectName('java.lang:type=Runtime'), 'Uptime' )/1000/60/60) + " hours"
file.writeLine 'cpuTime=' + server.getAttribute( new ObjectName('java.lang:type=OperatingSystem'), 'ProcessCpuTime' )
file.writeLine 'uptime=' + server.getAttribute( new ObjectName('java.lang:type=Runtime'), 'Uptime' )
</pre>
<h3>Summary</h3>
<p>As you can see, getting info via JMX is fairly easy and straightforward. There is other stuff we look at, such as our connection pool info. We use c3p0 for out pooling and it has a JMX component making that fairly easy as well.</p>
<p>As for processing time, it takes about 7 seconds or so to connect to our 5 servers and write out all of this data, so it is pretty quick. If you ran this locally on the machines it might be a second or so quicker since we are connecting remotely.</p>
<p>For the future, we are planning to add some JMX stuff to our actual application so we can monitor that as well. On the list are cache hits, requests per second, etc.</p>
<p>All together, it took me about 45 minutes to write this script and most of that was because I wasn&#8217;t familiar with the JMX api at all. After that I used JConsole to get the actual object names and property names, which was a big help.</p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/using-groovy-for-monitoring-via-jmx/feed</wfw:commentRss>
		</item>
		<item>
		<title>Google homepage has a major new update</title>
		<link>http://thebull.macsimumweb.com/google-homepage-has-a-major-new-update</link>
		<comments>http://thebull.macsimumweb.com/google-homepage-has-a-major-new-update#comments</comments>
		<pubDate>Thu, 16 Oct 2008 20:37:47 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/?p=251</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/google-homepage-has-a-major-new-update";</script>I&#8217;m a user of Google&#8217;s personal home page, and it just went through a big update. The tabs on the top are now on the left and even nicer is that gmail is now integrated in, so you no longer have to go to gmail to open mail and reply to them.
Very nice.
]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/google-homepage-has-a-major-new-update";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>I&#8217;m a user of Google&#8217;s personal home page, and it just went through a big update. The tabs on the top are now on the left and even nicer is that gmail is now integrated in, so you no longer have to go to gmail to open mail and reply to them.</p>
<p>Very nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/google-homepage-has-a-major-new-update/feed</wfw:commentRss>
		</item>
		<item>
		<title>FiBiRi.com running on Grails</title>
		<link>http://thebull.macsimumweb.com/fibiricom-running-on-grails</link>
		<comments>http://thebull.macsimumweb.com/fibiricom-running-on-grails#comments</comments>
		<pubDate>Tue, 05 Aug 2008 16:18:29 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[grails]]></category>

		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/?p=245</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/fibiricom-running-on-grails";</script>I&#8217;ve been working on FiBiRi.com on and off for about two months and I finally got it live. It is still kind of in alpha stage, but the functionality is largely there. This is my first serious application written using Grails, and I must say I&#8217;m hooked. 
Of course I&#8217;ve dabbled a bit here and [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/fibiricom-running-on-grails";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>I&#8217;ve been working on <a href="http://fibiri.com">FiBiRi.com</a> on and off for about two months and I finally got it live. It is still kind of in alpha stage, but the functionality is largely there. This is my first serious application written using <a href="http://grails.org">Grails</a>, and I must say I&#8217;m hooked. </p>
<p>Of course I&#8217;ve dabbled a bit here and there, but there is nothing like a real app to learn a new framework with. I had some minor pains but nothing too bad. All told I have about 120 to 160 hours in it which isn&#8217;t too shabby. A good portion of that time was learning grails and groovy so if I had to do again I could probably shave a good 20 or so hours off of that development time.</p>
<h4>Things to do</h4>
<p>There is still a lot content left to add along with the monetization stuff. I still have a few functionality items to add, mostly to do with the itineraries but I&#8217;m pretty happy with it. There is actually almost as many hours in gathering the content as there is in development time. Needless to say that ratio will only get wider as more content is added. It is also only focused on Las Vegas, but is set up so that any city or destination can be added so there is room to grow.</p>
<h4>Technical details</h4>
<p>There are 23 controllers, 18 domain classes, two services and two custom tag libraries along with 60 or so view pages (mostly admin). It is running in tomcat 6 behind nginx on a small <a href="http://linode.com">Linode.com</a> box with MySQL as the database. </p>
<p>I could have run it straight on tomcat, but chose to front it with nginx for a couple of reasons. One because I wanted to try nginx (I love it&#8230;) and two because I can later do some fancy caching behind it using memcached. </p>
<p>If anyone has any suggestions, feel free to let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/fibiricom-running-on-grails/feed</wfw:commentRss>
		</item>
		<item>
		<title>Please trap your errors!</title>
		<link>http://thebull.macsimumweb.com/please-trap-your-errors</link>
		<comments>http://thebull.macsimumweb.com/please-trap-your-errors#comments</comments>
		<pubDate>Mon, 21 Jul 2008 20:00:16 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/please-trap-your-errors/</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/please-trap-your-errors";</script>It just plain looks really, really bad when you have a public facing site and you don&#8217;t trap errors. Here is from Staples.com today (1pm PST):

]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/please-trap-your-errors";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>It just plain looks really, really bad when you have a public facing site and you don&#8217;t trap errors. Here is from Staples.com today (1pm PST):<br />
<a href='http://thebull.macsimumweb.com/wp-content/upload/2008/07/staples.jpg' title='Staples'><img src='http://thebull.macsimumweb.com/wp-content/upload/2008/07/staples.thumbnail.jpg' alt='Staples' /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/please-trap-your-errors/feed</wfw:commentRss>
		</item>
		<item>
		<title>Will document databases make an impact?</title>
		<link>http://thebull.macsimumweb.com/will-document-databases-make-an-impact</link>
		<comments>http://thebull.macsimumweb.com/will-document-databases-make-an-impact#comments</comments>
		<pubDate>Wed, 25 Jun 2008 15:51:07 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/will-document-databases-make-an-impact/</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/will-document-databases-make-an-impact";</script>There has been a lot of buzz about Amazon&#8217;s SimpleDB and other related projects like CouchDB, Google&#8217;s Datastore and Thrudb. Personally I think they will all find a niche in modern web applications, but what I find amusing are the nay-sayers that talk about the faults and even saying they aren&#8217;t even databases.
Come on, not [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/will-document-databases-make-an-impact";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>There has been a lot of buzz about Amazon&#8217;s SimpleDB and other related projects like CouchDB, Google&#8217;s Datastore and Thrudb. Personally I think they will all find a niche in modern web applications, but what I find amusing are the nay-sayers that talk about <a href="http://www.ryanpark.org/2008/04/top-10-avoid-the-simpledb-hype.html">the faults</a> and even saying <a href="http://natishalom.typepad.com/nati_shaloms_blog/2007/12/amazon-simpledb.html">they aren&#8217;t even databases</a>.</p>
<p>Come on, not a database? What are these people smoking? Since when does database == relational ? So they don&#8217;t support all transactions, aggregate functions or other features that are common to RDBMs. Did it ever occur to these people that not all applications need these features?</p>
<h3>Scalability</h3>
<p>The prominent feature for these document style databases is scalability. One guy equates scalability to the number of rows in the database. Uhh, maybe someone should explain to him what scalability means. Who cares if you can put millions of rows in your db if you only have 100 users? What about say a few hundred thousand rows but millions of users? It isn&#8217;t necessarily the number of rows you can store but how quickly you can get data out to your users. </p>
<h3>Where are my joins?</h3>
<p>Others go on and on about how you can&#8217;t do things like join data across tables. There are many big sites that actually store data in multiple places. Yep, denormalizing (gasp!) their data in the name of speed. Sharding also fits into this category. Although generally sharding happens on a traditional RDBMS, the effect is the same, spreading data out for scalability sake.</p>
<p>It all comes down to the right tool for the job. Until recently RDMBS were pretty much the only tool in the toolbox, whether you needed all the features or not. Now we have more options to choose from and I&#8217;ll bet that many choose the alternate route. All the nay-sayers are just scared.</p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/will-document-databases-make-an-impact/feed</wfw:commentRss>
		</item>
		<item>
		<title>Do you use ActiveMQ?</title>
		<link>http://thebull.macsimumweb.com/do-you-use-activemq</link>
		<comments>http://thebull.macsimumweb.com/do-you-use-activemq#comments</comments>
		<pubDate>Thu, 05 Jun 2008 16:09:42 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/do-you-use-activemq/</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/do-you-use-activemq";</script>So I read today where LinkedIN uses ActiveMQ as part of their architecture. I haven&#8217;t used ActiveMQ personally, but we use it for a project where I work and the guy that set it up absolutely hates it now.
We were looking to use a message server for a new project and started kicking around ideas. [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/do-you-use-activemq";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>So I read today where LinkedIN uses ActiveMQ as <a href="http://cookiesareforclosers.com/blog/2008/06/linkedin-architecture">part of their architecture</a>. I haven&#8217;t used ActiveMQ personally, but we use it for a project where I work and the guy that set it up absolutely hates it now.</p>
<p>We were looking to use a message server for a new project and started kicking around ideas. The primary requirement was multiple language support. New stuff is largely being done in Java but we also have a really large perl codebase and some backend stuff is still be done in perl. Naturally that made ActiveMQ a front runner because of its open language support. Once he got wind of the talks it was quickly shelved with &#8220;over my dead body&#8221;. </p>
<p>Turns out that despite the great documentation and its visibility, it doesn&#8217;t work quite as speedy as one would think. After fixing several bugs himself (out of order messages being one that I recall), the one glaring problem is performance. Seems that if a subscriber is a bit slow, the whole server becomes slow even on the receiving end. Well, that is just counter productive in my book. The whole idea of a message system is to eliminate these kinds of bottlenecks yes?</p>
<p>We then tried openAMQ (a C-based server) and that shelved too because it kept dropping messages. For the time being we settled on Websphere MQ which just makes me <a href="http://thebull.macsimumweb.com/top-5-reasons-ibm-is-pissed-off/">want</a> <a href="http://thebull.macsimumweb.com/are-there-any-good-vendors-out-there/">to</a> <a href="http://thebull.macsimumweb.com/a-better-websphere-tuning-tip/">puke</a>. I know IBM has had a message server forever, but I have yet to see a piece of software they&#8217;ve written that was worth a shit.</p>
<p>Hopefully we can find another solution before big blue takes a firm hold on us. Any suggestions?</p>
<p>Any really good experiences with ActiveMQ?</p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/do-you-use-activemq/feed</wfw:commentRss>
		</item>
		<item>
		<title>First real-world experience with Grails</title>
		<link>http://thebull.macsimumweb.com/first-real-world-experience-with-grails</link>
		<comments>http://thebull.macsimumweb.com/first-real-world-experience-with-grails#comments</comments>
		<pubDate>Tue, 03 Jun 2008 16:10:10 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/first-real-world-experience-with-grails/</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/first-real-world-experience-with-grails";</script>I&#8217;ve written a little bit about grails before, but until now I haven&#8217;t had a real application to build to really put it through it&#8217;s paces. At first I was going to build this application with Rails for the same reason, even deploy it on Glassfish with its RoR support. I don&#8217;t know though, something [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/first-real-world-experience-with-grails";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>I&#8217;ve written a little bit about grails before, but until now I haven&#8217;t had a real application to build to really put it through it&#8217;s paces. At first I was going to build this application with Rails for the same reason, even deploy it on Glassfish with its RoR support. I don&#8217;t know though, something about an application that requires a new instance for every request just seems wrong to me. Seems like such a flawed architecture that I just couldn&#8217;t bring myself to do it. Yea, there are other Ruby based web frameworks and I might try one at some time, but not this time.</p>
<p>I also have to say that I generally don&#8217;t generally like any kind of black-box magic frameworks. Code generation and such tend to make me cringe, but what the hell I was going to give it a shot. Needless to say so far I&#8217;m pretty darn impressed. While I&#8217;m not quite finished it is moving along very rapidly, and adding features is pretty damn easy. I would say I&#8217;ve put in about 50 hours or so over three weeks and I am at about 85% finished.</p>
<h2>What I like</h2>
<p>This is ironic part. I really hate tools like Hibernate that force you into a specific format. Most of this stems from my corporate application experience where databases are far more complex than what ORMs like Hibernate can handle. However in this case the <a href="http://grails.org/GORM">GORM</a> has been a wonderful time saver. Setting up relationships has been fairly easy, although I had a few head-scratching moments that weren&#8217;t quite textbook and the docs weren&#8217;t very clear on. </p>
<p>I also really like the URL mapping stuff. I&#8217;m sure Rails has a good URL mapping engine as well, but I really like being able to customize these as I see fit. I still get a bit confused on what return/render method to use in the controllers, but it hasn&#8217;t been too bad.</p>
<h2>What I don&#8217;t like</h2>
<p>About my only gripe so far is with the BootStrap class. This is a great idea and wonderful for development, but man it can be a pain. Actually the gripe isn&#8217;t so much as the BootStrap itself but with GORM. Go figure. </p>
<p>There are cases where I have a three level deep object graph and populating it isn&#8217;t as straightforward as it could have been. Most of my problems have been when I populate the leaf object and then I need to get that leaf object later for some other reason. The getBy and findBy methods will sometime return a null object, even when I know the parameters are good. I end up having to retrieve its parent and then getting the child out of there. I would say I&#8217;ve spent about 20%-25% of my time just trying to get my simple test data in. I could very well be doing something wrong, but the docs haven&#8217;t shown me anything different and what seems intuitive to me apparently isn&#8217;t. Oh well.</p>
<p>I haven&#8217;t been doing anything nearly as fancy as <a href="http://blogs.bytecode.com.au:80/glen/">Glen Smith</a> but isn&#8217;t a &#8220;hello world&#8221; app either. My current stats are:</p>
<p>16 controllers with 864 LOC<br />
12 domain classes with 245 LOC<br />
1 taglib with 22 LOC</p>
<p>I know I&#8217;m going to have to write at least one new tag lib for paging, as the provided paging taglib won&#8217;t work for me. A shame because I really need it. I should be done with domain classes but I&#8217;ll probably add a couple more controllers. </p>
<p>All in all I&#8217;m pretty happy with Grails and I look forward to getting this thing public.
<p>Get the latest celebrity news from around the web <a href="http://www.celebrityblender.com">here!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/first-real-world-experience-with-grails/feed</wfw:commentRss>
		</item>
		<item>
		<title>Lessons in scaling</title>
		<link>http://thebull.macsimumweb.com/lessons-in-scaling</link>
		<comments>http://thebull.macsimumweb.com/lessons-in-scaling#comments</comments>
		<pubDate>Tue, 03 Jun 2008 15:08:18 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/lessons-in-scaling/</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/lessons-in-scaling";</script>In my last post I wrote about some strange threading behavior in tomcat 6. After a couple weeks of struggling between iBatis, our app, our connection pool and even trying the NIO connector we finally narrowed it down to the connection pool. 
For some unknown reason, DBCP wasn&#8217;t taking the connections back into the pool. [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/lessons-in-scaling";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>In my last post I wrote about <a href="http://thebull.macsimumweb.com/strange-tomcat-threading-behavior/">some strange threading behavior</a> in tomcat 6. After a couple weeks of struggling between iBatis, our app, our connection pool and even trying the NIO connector we finally narrowed it down to the connection pool. </p>
<p>For some unknown reason, DBCP wasn&#8217;t taking the connections back into the pool. The result was the thread that was using them would hang and eventually tomcat would hang. How on earth DBCP has lived as long as it has with this problem is beyond me. We tried everything, even manually pulling the connection out of iBatis and closing it. Nothing worked. I could get DBCP to lock up with a connection pool of 150 and a user load of 50. Go figure.</p>
<h2>c3p0 to the rescue</h2>
<p>Thankfully there is another popular connection pool out there and it is c3p0. We swapped it in nice and easy (thanks Spring!) and presto, all our troubles went away. I could even overload the app (more concurrent users than connections available) and it wouldn&#8217;t die. It got slow, but it wouldn&#8217;t die. </p>
<p>Thanks to my finding, we swapped out DBCP as the pool that ActiveMQ was using and solved a few problems there as well. </p>
<p>Now our bottleneck is the communication between the application and our search engine, SOLR. That is to be expected somewhat as it opens an HTTP connection. We use SOLR for more than search however, it is also our navigation engine by means of faceting so needless to say we make a lot of calls to it. A little caching will solve that problem though and should be fairly easy to implement.</p>
<h2>What are the lessons learned?</h2>
<p>Don&#8217;t think any piece of the puzzle is immune to being the problem. My initial thoughts were that since DBCP has been around so long it couldn&#8217;t possibly be the problem. I spent most of my time in iBatis since I was new to it and thought maybe we were just doing something wrong. </p>
<p>In the end we were able to run load tests that were several times the capacity that our old (current) site sees. A good sign indeed.</p>
<p>Two tools helped more than anything else. JMeter for our load testing and JConsole, the built in JMX application for monitoring. With JConsole it was easy to see what threads were being locked, what they were waiting on and how many threads were running. Very, very handy indeed.
<p><a href="http://tinyurl.com/2eyjqv">$5 a month Ruby on Rails hosting</a>. No kidding! Unlimited domains, 7.5 TB of bandwidth</p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/lessons-in-scaling/feed</wfw:commentRss>
		</item>
		<item>
		<title>Strange tomcat threading behavior</title>
		<link>http://thebull.macsimumweb.com/strange-tomcat-threading-behavior</link>
		<comments>http://thebull.macsimumweb.com/strange-tomcat-threading-behavior#comments</comments>
		<pubDate>Fri, 02 May 2008 16:00:22 +0000</pubDate>
		<dc:creator>The Bull</dc:creator>
		
		<category><![CDATA[]]></category>

		<guid isPermaLink="false">http://thebull.macsimumweb.com/strange-tomcat-threading-behavior/</guid>
		<description><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/strange-tomcat-threading-behavior";</script>We are having some threading issues while load testing our production tomcat servers. When I fire up JMeter and hit it with about 50 users, tomcat grabs a ton of threads. Eventually this causes some instability and tomcat hangs. 
The weird thing is I can&#8217;t duplicate it locally. I hit my local running instance and [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript">dzone_url = "http://thebull.macsimumweb.com/strange-tomcat-threading-behavior";</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script><p>We are having some threading issues while load testing our production tomcat servers. When I fire up JMeter and hit it with about 50 users, tomcat grabs a ton of threads. Eventually this causes some instability and tomcat hangs. </p>
<p>The weird thing is I can&#8217;t duplicate it locally. I hit my local running instance and it might grab a few more threads which is to be expected, but not skyrocket up. At first I thought it was a problem with iBatis which had a known threading issue. But after upgrading to the latest beta it hasn&#8217;t solved anything. I also switched to using the session API in iBatis as well to no avail. </p>
<p>My gut tells me it isn&#8217;t directly tomcat&#8217;s fault since I can&#8217;t reproduce it and I don&#8217;t want to give up on tomcat just yet. However this problem is really keeping us from ramping up traffic on our beta site which of course doesn&#8217;t make the brass too thrilled.</p>
<p>In both cases tomcat is configured to use the APR connector and maxThreads are set at about 150. The only real difference in the configs is that production is in a cluster and is using large memory page configurations. Our production boxes have 16gb of RAM and 8 cores, so it the hardware has a lot of room to go.</p>
<p>Anyone have any thoughts about what is causing this?
<p><a href="http://tinyurl.com/2eyjqv">$5 a month Ruby on Rails hosting</a>. No kidding! Unlimited domains, 7.5 TB of bandwidth</p>
]]></content:encoded>
			<wfw:commentRss>http://thebull.macsimumweb.com/strange-tomcat-threading-behavior/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
