Do you have an ‘Application Server’? For some reason it’s a very popular choice to separate web applications into a front-end UI/Controller deployment, a separate server for back-end ‘Business Services’ and have them communicate via web services. I’ve never understood why this is a good idea and I’ve come to believe that people do it because of a number of architectural misconceptions.
Before I start I want to make a clear distinction between web applications and rich client applications. Rich clients do require an application server. I’m arguing that there’s no sane reason to build one for a web application. I’m also not talking about application service ‘Application Servers’ such as WebSphere or AppFabric.
1. Don’t confuse Logical and Physical architecture.
Good software design 101 says that you should separate concerns. You shouldn’t mix up UI concerns with data access concerns, and you should separate infrastructure from business logic. This is all good advice and working out the best ways to do it is really the core task of any programmer. However, when we say ‘separate’ we mean, ‘logically separate’. This means that these concerns should be separated in the structure of your software, it doesn’t mean that they have to be in separate assemblies, and it most emphatically shouldn’t mean that they should be deployed them on separate servers. As Martin Fowler says in Patterns of Enterprise Application Architecture, ‘The first rule of distributed components is don’t distribute your components’.
Having your business logic deployed on a separate server behind web services leads to all kinds of weird design pathologies. Because your controller logic can’t access your domain logic directly you can often find either business logic leaking into your controllers and UI, and/or chatty or over-complicated web service interfaces. This often can kill performance, which is ironic since performance is often used to justify the whole application server idea.
2. You can deploy multiple copies of the same assembly.
A common argument for application servers is that they aid reuse. By having all the business logic deployed on a single server, multiple applications will be able to reuse the same web services. For example, a fat client web forms applications will be able to share the same business logic as a web application. Messaging components will also be able to access those same web services.
The unwritten assumption is that we can only ever have one deployed copy of an assembly. However, the in-process object-oriented API of your domain entities is far better for reuse than a bunch of web services. There is nothing to stop you from having one deployment of your business logic in your web application, another in your application server that supports your rich clients and yet another in your messaging component.
It’s also often the case that when you start to have multiple applications consuming your web services, you find that their requirements are diverse enough to mean that reuse is minimal. The requirements of a request-response web application are not the same as an event driven web forms client.
3. There should only be one access point to my database.
Shared databases are a plague on business IT. Somewhere in the depths of your organisation are a tribe of grumpy trolls called DBAs. They form a protective barrier around ‘The Enterprise Database’. No one is allowed to change the schema without twenty committee meetings and two hundred pages of documentation signed in blood. No one is allowed to access the database except through stored procedures two thousand lines long, lovingly crafted over the last ten years by said DBAs. The reason for this sorry state of affairs is the horrible 90’s idea that a single relational database can be the core repository for the entire enterprise. Of course you don’t want to repeat this mistake, so you mandate that there must only be one access point to the database; the application server.
This is very sensible, you should only have a single access point to a database. However we’re repeating the confusion between logical and physical deployment again. You should only have one logical access point, but there is no reason why you shouldn’t deploy it multiple times.
4. An application server will help me scale.
No it won’t, it will make things worse. If you have a single web server, the most scalable physical architecture is to put everything on the same box, including the database. Network calls are expensive, very expensive. Each extra network hop you require your application to make to server a request will slow it down. More resources will be taken making the network connection than you will save by moving processing to another server.
If you have multiple web servers, you gain nothing from forcing your application to talk to the database via an application server. SQL Server can easily handle multiple connections from a number of web servers, and if you have more than five web servers you are already in a new zone of scalability requirements and you should be looking at message based asynchronous architectures such as CQRS. The same applies if you have expensive processing requirements, hand them off asynchronously.
So to conclude, think carefully before you decide you need an application server for your web application. Putting all the application code on the web server is a far better approach. You can have a farm of servers sharing a single database and it will scale well. I did some consultancy for the UK property website findaproperty.com who use this approach very successfully, and Stack Overflow has a very similar architecture. Both serve around half a million page views per day, findaproperty with four web servers, Stack Overflow with two. Of course, if you are Google or Facebook, you need a different approach… and better advice than I can give.
13 comments:
Although I agree with you, Silverlight is an interesting case, as typically all of the data access preformed is via web services.
Good advice, 100% agreed.
rusmo, Silverlight falls into the category of rich client, then you do need an 'application server', although in fact it doesn't really change the architecture that much, since you are simply swapping a web server serving HTML to one serving XML or JSON.
Very nice post indeed! I have to say I agree with most everything you've brought forward here. Now if only someone could dig deeper into the parts of CQRS :)
Good call - but I'd like to make one correction. Scalability doesn't mean improving latency / performance, it refers to the ability to increase capacity if required. So an architecture that's designed to work on a single web / application / database server is in fact the least scalable thing there is, because all you can do is buy a faster processor / ram / harddisk for the one machine. It probably is the most performant scenario there is (assuming you don't have too many users :P )
I agree with you but I've found in my domain (banking systems) it is a security requirement that they be physically separated, the web tier goes in the DMZ and the application tier must go deep behind additional firewalls.
We use Application Servers running Web Services as a security control point. This is especially important when you are dealing with personal information (SSN, Credit Card Numbers, etc).
One of our applications needs to have SSNs, but we need to make sure that nobody can get SSNs out of the system using the Web UI. When you have code that allows uploads, you have a surface area that could be compromised compared to a server that doesn't allow that. So, somebody could compromise the web server and never gain access to the SSN because the only app that can read SSNs is the Web Service, there is no code to return SSN via a web service call.
The article shows some degree of immaturity towards the understanding of architecture principles.
When I read the comment made "...If you have a single web server, the most scalable physical architecture is to put everything on the same box, including the database..."
hmm, you have a lot to learn young padowan.
The the most scalable physical architecture is to put everything on the same box, including the database?
You want to take those words back?
Finally someone blogs about it. I've been doing logical separation for years, never jumped on the application server bandwagon. As an example: in a custom ERP system that I develop and maintain, I have a central business model (which produces a Eclipselink postprocessed jar), and that jar is used in a Swing fat client, EDIFACT im/exporter, webservice for an Android app, backoffice website.
So in the end there are 20 swing client, but about 10 batch processes all accessing the database through the BM. Simple. Straight forward. Fast.
This is from 2010, would you really recommend CQRS in 2014? Thought not.
I simply cannot agree with this notion.
Here is why.
1. The main reason for the physical separation of web servers and application servers is internet security. Web servers reside in a DMZ which has servers surround by firewalls. These web applications are written as facades to services in Application Tier on the other side of a firewall. Professional hackers are not given DATABASE strings or exception hints.
2. Deploying the same libraries for different front-ends will lead to version-hell. We use multi-versioned services to avoid this.
3. Scalability. Putting all the logical tiers on one computer will definitely cause a single point of failure bottle neck.
And it is NOT so, that web server farm plus application farm is more inefficient than having it all on one computer or even in a single farm. When the traffic exceeds 50000 transaction per minute, having 3 tiers (Web, app, database) in different farms IS MOST efficient and VERY scalable.
This article may be good for a Small to Medium enterprise (but I doubt it), but for the Large enterprise or success web site 3-tier architecture is a must!!
Regards GregJF
Post a Comment