<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JAW Speak &#187; architecture</title>
	<atom:link href="http://jawspeak.com/category/architecture/feed/" rel="self" type="application/rss+xml" />
	<link>http://jawspeak.com</link>
	<description>Jonathan Andrew Wolter</description>
	<lastBuildDate>Fri, 30 Jul 2010 20:39:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Session State &#8211; it&#8217;s not complicated, but options are limited</title>
		<link>http://jawspeak.com/2010/07/30/session-state-its-not-complicated-but-options-are-limited/</link>
		<comments>http://jawspeak.com/2010/07/30/session-state-its-not-complicated-but-options-are-limited/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 20:39:08 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=277</guid>
		<description><![CDATA[Reading time: 3 &#8211; 4 minutes

			
				
			
		
Web apps have numerous choices for storing stateful data in between requests. For example, when a user goes through a multi-step wizard, he or she might make choices on page one that need to be propagated to page three. That data could be stored in http session. (It also could [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 3 &#8211; 4 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2010%2F07%2F30%2Fsession-state-its-not-complicated-but-options-are-limited%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2010%2F07%2F30%2Fsession-state-its-not-complicated-but-options-are-limited%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>Web apps have numerous choices for storing stateful data in between requests. For example, when a user goes through a multi-step wizard, he or she might make choices on page one that need to be propagated to page three. That data could be stored in <a href="http://en.wikipedia.org/wiki/HTTP">http</a> <a href="http://en.wikipedia.org/wiki/Session_%28computer_science%29">session</a>. (It also could get stored into some backend persistence and skip session altogether).</p>
<p>So where does session get stored? There are basically four choices here.</p>
<ol>
<li>Store state on one app server, i.e. for java in HttpSession. Subsequent requests need to be pinned to that particular app server via your load balancer. If you hit another app server, you will not have that data in session.</li>
<li>Store state in session, and then replicate that session to all or many other app servers. This means you don&#8217;t need a load balancer to anchor a user to one app server; multiple requests can either hit any app server (full replication). Or use the load balancer to pin to particular cluster (themselves replicating sessions, and giving higher availability). Replication can be smart so only the deltas of binary data are multicast to the other servers.</li>
<li>Store the state on the client side, via cookies, hidden form fields, query strings, or client side storage in flash or html 5. Rails has an option to store it in cookies automatically. Consider encrypting the session data. However, some of these options can involve a lot of data going back and forth on every request, especially if it&#8217;s in a cookie and images/scripts are served from the same domain.</li>
<li>Store no state on app servers, instead write everything in between requests down to backend persistence. Do not necessarily use the concept of http session. Use id&#8217;s to look up those entities. Persistence could be a relational database, distributed/replicated key/value storage, etc. Your session data is serialized in one big object graph, or as multiple specific entries.</li>
</ol>
<p>What you choose is up to many factors, however a few guidelines help:</p>
<ol>
<li>Try to keep what is in session small.</li>
<li>If possible, keep session state on the client side.</li>
<li>Prefer key/value storage replicated among a small cluster over replicating all session state among all app servers.</li>
<li>Genuinely consider sticky sessions, which home users to a particular app server. Many benefits abound, including what Paul Hammant talks about w.r.t Servlet spec 7.7.2 <a href="http://paulhammant.com/blog/appengines-blind-spot.html">Appengine&#8217;s Blind Spot</a>.</li>
<li>If you serialize an object graph, recognize that when you do a deployment it will probably mean existing sessions are now unable to be deserialized by the newly deployed app. Avoid this by using your load balancer to swing new traffic into the new deployments, monitor errors, and then let the old sessions expire before switching all users over to the new deployment. Bleed them over.</li>
<li>Session is not for caching. It may be tempting to store data in session for caching purposes, but soon you will need a cache.</li>
<li>Store in session what is absolutely necessary for that user, but not more. See caches, above.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2010/07/30/session-state-its-not-complicated-but-options-are-limited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplicity is Better for Deploying in Production Web Architectures</title>
		<link>http://jawspeak.com/2010/01/30/simplicity-is-better-for-deploying-in-production-web-architectures/</link>
		<comments>http://jawspeak.com/2010/01/30/simplicity-is-better-for-deploying-in-production-web-architectures/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 18:20:49 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=180</guid>
		<description><![CDATA[Reading time: 5 &#8211; 8 minutes

			
				
			
		
Engineering something to be scalable, highly available, and easily manageable has been the focus of much of my time recently. Last time I talked about spiderweb architecture, because it has attributes of scalability and high availability, yet comes with a hidden cost. Complexity.
Here is a fictional set of questions, and [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 5 &#8211; 8 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2010%2F01%2F30%2Fsimplicity-is-better-for-deploying-in-production-web-architectures%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2010%2F01%2F30%2Fsimplicity-is-better-for-deploying-in-production-web-architectures%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>Engineering something to be scalable, highly available, and easily manageable has been the focus of much of my time recently. Last time I talked about <a title="Large Web App Architecture: Yes to Thicker Stack on One Hardware Node, No to Beautiful “Redundant” Spiderwebs" href="http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/">spiderweb architecture</a>, because it has attributes of scalability and high availability, yet comes with a hidden cost. Complexity.</p>
<p>Here is a fictional set of questions, and my responses for the application architecture.</p>
<p>Q: Why does complexity matter?<br />
JAW: Because when your system is complex, there is less certainty. Logical branches in the possible state of a system mean more work for engineers to create a mental model, and decide what action to take. Complexity means there are more points of unique failure.</p>
<p>Q: But my team is really, really smart; my engineers can handle clever and complex mental models!<br />
JAW: That wasn&#8217;t a question, but I do have a response.<span style="background: #ffff99;"> <em>Given a team at any moment in time, there is a finite amount of complexity that the team can deal with. Complexity can be in the application&#8217;s logic, dealing with delivering business value. Or, it can be in non functional requirements. If the NFR&#8217;s can be met with lower complexity, this will translate directly to more business value.</em></span> A team will grow in their ability to manage complexity as they understand more and more of it, and team size can increase. Although those productivity increases can be used for business value, or complex architectures. And often, NFR&#8217;s <a href="http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/">can be met</a> while still achieving simplicity.</p>
<p>Q: So how do I deal with a large, complex application which needs an emergency fix on one of the small components?<br />
JAW: Yes, I know the scenario. You want to make a small change into production, but it sounds less risky to only push one part. Here&#8217;s my recipe for success: <em>make every deployment identical, and automated</em>. (Ideally push into production from continuous builds, with automated testing.) In the event of an emergency push into production, alter the code from your version control tag, and deploy that as you would every other push. My colleague <a href="http://paulhammant.com/">Paul Hammant</a> call non-standard, risky pushes &#8220;white knuckle three-in-the-morning deployments.&#8221;</p>
<p>Don&#8217;t make the e-fix a one-off, non-standard production push. Have the entire system simple, and repeatable. <em>With repeatability and automated repetition comes security</em>. Very flexible (read: complex), extensible (read: rarely tested day to day) hooks can be built into a system, in order to make it <em>possible</em> to push just one small component into production. However in reality unused code becomes stale, and when a production emergency happens, people will be so scared to try these hooks. Or if they do, there is a greater risk of a misconfiguration, and failure. Which will necessitate a fix of the failed fix which tried to fix the original tiny defect. More complexity. Blowing the original availability requirements out of the water.</p>
<p>Q: So, what is simplicity?<br />
JAW: My definition says: <em>Simplicity</em> is the preference of fewer combinatorial states a system can be in. Choose defaults over</p>
<p>I recently read a quote from <a href="http://highscalability.com/youtube-architecture">High Scalability</a>, which I think gives a good definition of what simplicity is (emphasis added):</p>
<blockquote><p>&#8220;Keep it simple! Simplicity allows you to rearchitect more quickly so you can respond to problems. It&#8217;s true that nobody really knows what simplicity is, but <span style="background: #ffff99;"><em>if you aren&#8217;t afraid to make changes then that&#8217;s a good sign simplicity is happening.</em></span>&#8220;</p></blockquote>
<p>[Caveat: some complexity makes sense, it's just too much in the wrong places increases risk. And there is a threshold everyone needs to find: how much risk, how much flexibility, and how much energy to devote to reducing the risk while keeping high flexibility.]</p>
<p><strong>Update</strong>: Thanks to <a href="http://lucas-ward.blogspot.com/">Lucas</a>, for pointing me to an interesting article about <a href="http://arstechnica.com/business/data-centers/2010/02/what-second-life-can-teach-all-companies-about-scaling-web-apps.ars/2">second life scaling</a>:</p>
<blockquote><p>A preconditon of modern manufacturing, the concept of interchangeable parts that can help simplify the lower layers of an application stack, isn&#8217;t always embraced as a virtue. A common behavior of small teams on a tight budget is to tightly fit the building blocks of their system to the task at hand. It&#8217;s not uncommon to use different hardware configurations for the webservers, load balancers (more bandwidth), batch jobs (more memory), databases (more of everything), development machines (cheaper hardware), and so on. If more batch machines are suddenly needed, they&#8217;ll probably have to be purchased new, which takes time. Keeping lots of extra hardware on site for a large number of machine configurations becomes very expensive very quickly. This is fine for a small system with fixed needs, but the needs of a growing system will change unpredictably. When a system is changing, the more heavily interchangeable the parts are, the more quickly the team can respond to failures or new demands.</p>
<p>In the hardware example above, if the configurations had been standardized into two types (say Small and Large), then it would be possible to muster spare hardware and re-provision as demand evolved over time. This approach saves time and allows flexibility, and there are other advantages: standardized systems are easy to deploy in batches, because they do not need assigned roles ahead of time. They are easier to service and replace. Their strengths and weaknesses can be studied in detail.</p>
<p>All well and good for hardware, but in a hosted environment this sort of thing is abstracted away anyway, so it would seem to be a non-issue. Or is it? Again using the example above, replace &#8220;hardware&#8221; with &#8220;OS image&#8221; and many of the same issues arise: an environment where different components depend on different software stacks creates additional maintenance and deployment headaches and opportunities for error. The same could be said for programming languages, software libraries, network topologies, monitoring setups, and even access privileges.</p>
<p><span style="background: #ffff99;">The reason that interchangeable parts become a key scaling issue is that a complex, highly heterogeneous environment saps a team&#8217;s productivity</span> (and/or a system&#8217;s reliability) to an ever-greater degree as the system grows. (Especially if the team is also growing, and new developers are introducing new favorite tools.) The problems start small, and grow quietly. Therefore, a great long-term investment is to take a step back and ask, &#8220;what parts can we standardize? Where are there differences between systems which we can eliminate? Are the specialized outliers truly justified?&#8221; A growth environment is a good opportunity to standardize on a few components for future expansion, and gradually deprecate the exceptions.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2010/01/30/simplicity-is-better-for-deploying-in-production-web-architectures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Large Web App Architecture: Yes to Thicker Stack on One Hardware Node, No to Beautiful &#8220;Redundant&#8221; Spiderwebs</title>
		<link>http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/</link>
		<comments>http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 05:55:21 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=118</guid>
		<description><![CDATA[Reading time: 4 &#8211; 7 minutes

			
				
			
		
My last client our team worked with had a large ecommerce operation. Yearly revenue in the new site is in the high single digit billions of dollars. This necessitates extremely high availability. I will draw an initially favorable looking configuration for this high availability (&#8220;beautiful spiderwebs&#8221;), but then tear it [...]]]></description>
			<content:encoded><![CDATA[<p>Reading time: 4 &#8211; 7 minutes</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F19%2Flarge-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=?url=http%3A%2F%2Fjawspeak.com%2F2009%2F08%2F19%2Flarge-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs%2F&amp;style=normal&amp;service=bit.ly" height="61" width="51" /><br />
			</a>
		</div>
<p>My last client our team worked with had a large ecommerce operation. Yearly revenue in the new site is in the high single digit billions of dollars. This necessitates extremely high availability. I will draw an initially favorable looking configuration for this high availability (&#8220;beautiful spiderwebs&#8221;), but then tear it apart and suggest an alternative (&#8220;Thicker Stack on One Hardware&#8221;).</p>
<h3>1. &#8220;Beautiful Spiderwebs&#8221; &#8211; Often Not Recommended</h3>
<p>Here&#8217;s one common way people could implement high availability. Notice how there are always multiple routes available for servicing a request. If one BIG IP goes down, there is another to help. And this could be doubled with multiple data centers, failed over with DNS.</p>
<p>The visible redundancy and complexity in one diagram may be appealing. One can run through scenarios in order to make sure that yes, we can actually survive any failure and the ecommerce will not stop.</p>
<p><a title="not recommended spiderweb tiers by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3836184306/"><img src="http://farm3.static.flickr.com/2588/3836184306_96e6a18f29.jpg" alt="not recommended spiderweb tiers" width="443" height="500" /></a></p>
<p>So then what could make this my <em>Not Recommended </em>option?<em><br />
</em></p>
<h3>2. Martin&#8217;s Reminder how to Think About Nodes</h3>
<p>Fowler reminded us in <a href="http://www.amazon.com/gp/product/0321127420?ie=UTF8&amp;tag=econtechblog-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0321127420">Patterns of Enterprise Application Architecture</a> how to look at distribution and tiers. For some reason people keep wanting to have certain &#8220;machines running certain services&#8221; and <em>just</em> make a <em>few</em> service calls to stitch up all the services you need. If you&#8217;re concerned about performance, though, you&#8217;re a looking for punishment. Remote calls are several orders of magnitude greater than in process, or calls within the same machine. And this architectural preference is rarely necessary.</p>
<p>One might lead to the first design with the logic of: &#8220;We can run each component on a separate box. If one component gets too busy we add extra boxes for it so we can load-balance our app.&#8221; Is that a good idea?</p>
<p><a title="fowler distributed objects not recommended by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3835392251/"><img src="http://farm3.static.flickr.com/2551/3835392251_d4824c236f.jpg" alt="fowler distributed objects not recommended" width="500" height="299" /></a></p>
<p>The above is not recommended:</p>
<blockquote><p>A procedure call between two separate processes is orders of magnitude slower [than in-process]. Make that a process running on another machine and you can add another order of magnitude or two, depending on the network topography involved. [PoEAA Ch 7]</p></blockquote>
<p>This leads into his <em>First Law of Distributed Object Design: Don&#8217;t distribute your objects!</em></p>
<p>The solution?</p>
<blockquote><p>Put all the classes into a single process and then run multiple copies of that process on the various nodes. That way each process uses local calls to get the job done and thus does things faster. You can also use fine- grained interfaces for all the classes within the process and thus get better maintainability with a simpler programming model. [PoEAA Ch 7]</p></blockquote>
<p><a title="fowler clustered application recommended by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3835392281/"><img src="http://farm4.static.flickr.com/3580/3835392281_35920eff8d.jpg" alt="fowler clustered application recommended" width="463" height="307" /></a></p>
<h3>3. &#8220;Strive for Thicker Stack on One Hardware Node&#8221; &#8211; Recommended</h3>
<p>Observe the recommended approach below. There is still an external load balancer, but after a request is routed to an Apache/Nginx/etc front end, you&#8217;re all on one* machine.</p>
<p>If one tier fails on a node, pull the whole node out from rotation. Replace it. And re-enter it in the mix.</p>
<p>Your companies teams have worked together to be able to deploy modular services. So when your ecommerce site needs a merchant gateway processing service, you can include that (library or binary) and run it locally on your node, making a call through to it as needed.</p>
<p>Services are also simpler to deploy, upgrade and monitor as there are fewer processes and fewer differently-configured machines.</p>
<p><a title="recommended thicker nodes tiers by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3835392219/"><img src="http://farm3.static.flickr.com/2525/3835392219_88ca43602b.jpg" alt="recommended thicker nodes tiers" width="500" height="429" /></a></p>
<p>(* I understand there may be the occasional exception for remote calls that need to be made to other machines. Possibly databases, mcached obviously third party hosted services, but the point is <em>most everything else</em> need not be remote.)</p>
<h3>4. But, Practically Speaking How Far Do We Go?</h3>
<p>A caveat first: these benefits get pronounced as you have more and more nodes. (And thus, more and more complex of spiderwebs of unnecessary failover).</p>
<p>Should there be a database server running on each node? Probably not at first. There is a maintenance associated with that. But after sharding your database and running with replication, why not? This way if a node fails, you simply pull it out and replace it with a functioning one.</p>
<h3>5. Checklist of Takeaway Lessons</h3>
<ol>
<li>Keep it local. Local calls orders of magnitude faster than remote calls.</li>
<li>Make services modular so they don&#8217;t need to be remote, yet still have all the organizational benefits of separate teams.</li>
<li>Simplicity in node-level-redundancy is preferred over tier-level-redundancy.</li>
</ol>
<p>Often, people think of high availability with terms such as the following: <a href="http://en.wikipedia.org/wiki/Round-robin_scheduling">Round Robin</a>, <a href="http://en.wikipedia.org/wiki/Load_balancing_%28computing%29">Load Balancing</a>, and <a href="http://en.wikipedia.org/wiki/Failover">Failover</a>. What do you think of? Leave a comment below with how you meet the trade-offs of designing for HA as well as architectural decisions of low latency.</p>
]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2009/08/19/large-web-app-architecture-yes-to-thicker-stack-on-one-hardware-node-no-to-beautiful-redundant-spiderwebs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
