When do you need a 3-tier architecture?
Context is key, understand the trade-offs
I've been putting together the content for a talk that I'm doing at the ArchSummit 2012 in China next month about designing for security* (如何设计安全的架构) and one of the things I'll be talking about is when to use an n-tier architecture (where typically n=3) from a security point of view. But this got me thinking about n-tier architectures in general given that it's now 2012. I often see n-tier architectures presented in my training course when groups are designing a solution for the case study, but sometimes the justification is weak.
Traditional wisdom says that 3-tier architectures are "good". Is this still true in 2012? Let's keep this simple and restrict our thinking to the domain of Internet facing web applications that use a 3-tier architecture consisting of physically separate web server (web-tier), application server (middle-tier) and database (data-tier).
You don't need an application server
After some digging around, I found this blog entry by Mike Hadlow called You Don't Need an Application Server, where he's referring to middle-tier application servers rather than products that are badged as application servers (e.g. WebSphere, JBoss, etc). It's worth a read because it challenges a number of common preconceptions.
Except when you do
Rather than simply agree with the title of his blog entry, I want to ask, "when do you actually *need* a 3-tier architecture?". The answer to this question isn't black and white at all because much of the time the use of a 3-tier architecture depends on the context of where you are and what you're trying to achieve. Here are some common arguments and counter-arguments concerning the use of a middle-tier application server.
- Security: A physically separate middle-tier application server can increase security because it adds an extra level of indirection between the web server and the database. This means no direct route from the web server to the database server and (e.g.) SQL protocols/ports don't need to be allowed/opened on DMZ firewalls. If your web server gets hacked, your application server is safe. Also, the attack surface on the web server is reduced because there is a reduced amount of code, etc running on the web server. As a counter-argument, adding a level of physical indirection doesn't necessarily provide more security. In reality, how good are we as developers at creating secure middle-tiers? Security context propagation is complex and I've seen many middle-tiers that simply wrap up business logic/data access and expose them to the web-tier as a collection of unsecured web services.
- Performance and scalability: A 3-tier architecture is more scalable than a 2-tier architecture because the web-tier and middle-tier can be scaled differently if necessary. An application server can be used to cache persistent data to increase performance and scalability. Counter-arguments include that scaling just a web server is simpler and caching could be done either locally in the web server or by duplicating the data in a different format (e.g. a NoSQL store alongside a SQL database).
- Reuse and maintenance: A single physical middle-tier can be shared by a number of clients, so reuse and maintenance is increased. As highlighted in Mike's blog entry, a counter-argument is that this is possible by creating reusable components that are simply deployed multiple times.
- etc...
Context is key, understand the trade-offs
The list above is only a quick summary of some key points but one counter-argument for all of the concerns above is the increase in cost and complexity. Creating a 3-tier architecture is relatively straightforward, but getting it right involves a good deal of effort. I still remember the panacea created by J2EE application server vendors that basically said, "don't worry about security, scalability, transactions, etc ... we'll do all that for you!".
When making architectural decisions, context is key. Often the reason for introducing a physically separate application server is because "our organisation doesn't permit SQL traffic from machines in the DMZ". It's certainly *a* reason, but perhaps one that should be challenged, particularly if reducing cost and complexity are important. You *will* be making some trade-offs and it's crucial that understand what they are.
Back to my original question then ... when do *you* use a 3-tier architecture and why?
* Of course, the irony of this talk is that I'm not a security expert and that's really the point. As a technical lead/software architect, you can't be a specialist in everything but you do need a general awareness so that you can try to do "the right thing", knowing where to get help from those that are specialists.
Re: When do you need a 3-tier architecture?
Re: When do you need a 3-tier architecture?
Re: When do you need a 3-tier architecture?
I personally prefer lots of small components, offering APIs or consuming messages, that do one thing and one thing only. These get plumbed together to make a single service. With the right deployment environment, new services are simple to add. Horizontal scaling becomes much easier, with performance problems being localised to single services, and much easier to address, since drastic changes like rewrites and complete datastore changes are feasible. Code bases remain small and simple, and can be written in the right language using the right technologies for the job - a comet API might use NodeJS while the authentication service uses Scala. If it turns out that you chose the wrong database for a service, it's easy to replace, we replaced the database of a feed service in a large social network with zero downtime in only a few months, including all the work that was done in performance testing and proving that the new database was the right tool for the job.

