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.