What is an App Server?
It's worth reconsidering what the definition of an application server is, really, to make sure that the term means the same thing to everyone who uses it - and everyone does use it, often meaning completely different things. So let us ask the question: what is an application server? Which attributes from the following list are part of an application server?- Serves up web pages
- Provides a container model for applications
- Provides services for applications
- Adheres to a specification controlled by industry
- Distributes requests across multiple physical servers
- Provides management and/or development tools
The real definition of an application server in the Java EE world is more than servlets, JSP, database connection pooling. These are just a few pieces of the Java EE container model2, where an application is split into a server portion and a client portion3. The server itself is composed of different containers, each providing different services to an application.
There are lots of service containers! There's the servlet container that presents the front-end user interface4, the Enterprise JavaBean container that (presumably) manages business logic, a naming and directory interface, a message service, an adapter service that allows access to non-Java or other non-managed services, a security container... the list goes on5.
Since Java EE is designed to be able to handle large, complex applications, the container model tends to have a built-in level of complexity that can be daunting, to say the least, and historically was challenging even to advanced developers.
Most applications only use one or two parts of an application server, usually zeroing in on servlets and database connectivity; frameworks like Spring sprang up to make much of the container model unnecessary. There were costs to this, in that the applications ended up managing their own resources, but that was all right for most cases6... and the dependency injection frameworks restored so much simplicity to the development model that they made up for any weaknesses they may have had. (Most criticisms of the J2EE development model centered around the complexity of configuration and deployment.)
The result of applications using few services in an application server is that the definition of an application server becomes simpler. To a J2EE traditionalist, someone referring to Tomcat as their application server used to be a horror. Now, though, with simpler development models, Tomcat and Jetty are fully recognizable as "application servers" - even while not meeting the heavier requirements of the full specification7.
The problem with the Java EE specification and the notion of profiles is that it's still tied to the concept of request/response. A browser or client application sends a request, via HTTP, or CORBA, or whatever transport is chosen; the server then takes that request and farms it to an installed module, which responds (presumably over the same transport.)
Is that a big problem? Of course not. Chances are that 99% (or more!) of the applications in the world fit that model. That may be because one chooses how to build based on what tools you have - you don't use a screwdriver when all you have is a nail - but the fact remains that in general, the request/response model, using HTTP as a transport, is good enough for most applications. (If it weren't, people wouldn't continue to use the web as an application delivery mechanism.)
There are, however, applications or tasks for which request/response isn't enough.8 The Java EE specification has started to acknowledge this through the definition of EJB timers, which can themselves initiate processes after time lapses.
In fact, EJB timers are a huge shift in mindset for Java EE.
J2EE - the prior name for the specification - allowed for components (through the J2EE Connector Architecture specification9) which were able to manage all kinds of tricks, such as creating threads (which could, of course, spawn events), accessing filesystems10, or throttling external requests, or polling mail servers11.
With EJB timers, however, the need to spawn threads to watch for time lapses goes away. This doesn't get rid of the need for JCA components, but it goes a long way to handling the most common need that a JCA component would fulfill.
However, while EJB timers and JCA components are great enablers, and it's possible to scale up enormously with Java EE through the use of a good JMS container, the fact remains that the Java EE specification is only going to serve a wide middle ground of applications. It's sufficient for most applications, to be sure!
However, for some applications, even servlet engines are heavy - and for applications that need to run in realtime or need to scale up to handle incredible loads, Java EE has not yet truly been able to satisfy requirements.
Java EE's status as a set of specifications leads to some interesting problems, based on reliance on specific implementations of the specifications. An example? See http://blog.griddynamics.com/2008/07/gridgain-on-ec2.html, "Scalability Benchmark of Monte Carlo Simulation on Amazon EC2 with GridGain Software." The benchmark ran a computationally intensive algorithm on 512 EC2 instances, and boasted that it only had a 20% degradation after 256X increase in load.
That sounds impressive, until you note that the JMS container was the bottleneck here. All it had to do was serve out new data, a task for which it should have been perfect... yet it introduced a 20% loss in performance. It's important to remember that only one JMS container - Sun's Open MQ - was tested, although the use of ActiveMQ "ran into scalability issues." Other JMS containers may do better, and one certainly hopes this is the case, but these results are not encouraging.
Let's be clear: JMS itself is not to blame. It's just a specification. In this case, it's the container that deserves what blame there is - but people rarely understand or measure the container's actual impact, assuming that they can "use container X" and it'll work for them. It's a failure of expectation, not of platform... but the platform deserves the blame for setting the expectation.
One takeaway from the Grid Dynamics benchmark, however, was entirely valid, though: the use of the grid has enormous potential.
Grid Dynamics' test was not especially instructive as far as the power of the grid is concerned. (Nikita Ivanov said that the test was primarily to prove Amazon EC2's capabilities to run 512 nodes at the same time on the same application12.) However, if you were able to easily scale out and manage transactions and data on the grid, the ability to scale linearly (or nearly so) means you can have as much computing power as you can afford - literally, whether it's a $300 desktop machine lurking on a network, or an EC2 node you're paying for on an hourly basis.
The challenges for the grid fall in three primary areas: architecture, coding methodologies, and deployment.
Architectural changes for the grid can be a significant challenge simply because we, as developers, tend to accept architectural limits as a matter of course - and such limits aren't necessarily part of a grid13.
Coding methodologies also change. As Java EE is a largely request/response paradigm, developers learn to think in terms of single producers and consumers, and tend not to scale a given process out - simple load balancing is more preferred, from anecdotal studies. While it's impossible to give a generalized model for programming a grid-aware application, it's safe to say that truly leveraging the grid will impact your final model in fairly severe ways14.
Deployment issues around the grid mostly center around dynamic provisioning, where the systems on the grid participate only if they're needed.
Cloud computing isn't the only thing being added to the definition of an application server. Application servers for Java are traditionally packaged in very specific ways: web archives, ejb jars, enterprise archives, resource archives15. With the advent of OSGi, a specification for modules becomes a platform for application servers.
Right now, there's really only one major application server based on OSGi - SpringSource' Application Platform - although other application servers are starting to head that way, such as Glassfish. With OSGi, deploying an application becomes a matter of specifying a module, its dependencies, and what it handles - which may or may not be in the set of things one normally considers as "application server territory."
SpringSource' Application Platform is called a platform rather than an application server, but that's because "application server" means Java EE to many people! The meaning of "application server" should be divorced from "Java EE," rather than creating new memes for people to remember.
The definition of an application server used to be simple: it was something that helped applications. SAP defined itself as an application server, and was correct to do so, long before they offered NetWeaver. In a Java context, though, "application server" has been narrowed to mean a J2EE server. Now, however, with the advent of cloud computing, the definition simply has to widen again, to include not only Java EE, but any application platform that provides services that developers can leverage.
That's what it was, and what it should always have been, and what it should be now.
Footnotes
1http://searchsqlserver.techtarget.com/sDefinition/0,,sid87_gci211584,00.html,
"What is application server?" Note the emphasis on HTTP as a
transport.
2http://java.sun.com/javaee/5/docs/tutorial/doc/bnabo.html,
"Java EE Containers."
3The
client portion of a Java EE application can be seen as one (or more)
of three environments: a client-side rich application, a web
browser, or an applet running inside of a web browser.
4This
is often with HTTP, although
other protocols like SMTP are fully possible if you use a different
port and, well, use Servlet instead of HttpServlet...
5Interested
in the whole list? See
http://java.sun.com/javaee/5/docs/tutorial/doc/bnacj.html,
"Java EE APIs."
6With
the advent of Sarbanes-Oxley, this changed somewhat: an application
should not manage its own database passwords and the like. The Java
Naming and Directory Interface was designed to isolate confidential
information from the developer: see
http://www.ibm.com/developerworks/library/j-jndi/?ca=dnt-62,
"The role of JNDI in J2EE"
7In
fact, the Java EE 6 specification created the idea of "profiles,"
built around the idea that containers like Tomcat are, in fact,
acceptable application servers, and should be recognized as such by
the specification.
8For
example: batch processing, map/reduce architectural problems,
complex flows without a specific request/response phase, or
event-driven architectures - although it should also be noted that
when all you have is a hammer, everything looks like a nail. People
can use and have used J2EE for all of these, no matter what a pain
it was to do so.
9http://java.sun.com/j2ee/connector/,
"J2EE Connector Architecture," a rather underappreciated
specification thanks to its arcane structure.
10Thus
enabling safe usage of Lucene: see https://lucenerar.dev.java.net/
and https://lucene-connector.dev.java.net/
11A
mail polling JCA component is the basis for the JCA tutorial.
12"I
... don't think that Grid Dynamics claims anything beyond just this
test - you can simply perform computationally intensive tasks with
almost linear scalability on 512-node strong Amazon EC2 cloud,"
from
http://www.theserverside.com/news/thread.tss?thread_id=50262#266007
13In
the interest of product neutrality, I don't think I can fairly go
into more on architectural changes for a grid. I work for GigaSpaces
Technologies; my bias is pretty easy to discover.
14Note
that there are (at least) two vendors who might protest that
statement: Azul and Terracotta. Both claim to take an application
written traditionally and scale them out. I won't say otherwise;
however, I'd say that even with Azul and Terracotta DSO you'll see a
greater benefit from modifying your architecture to leverage the
platforms' capabilities.
15JbossAS
used to inspire a lot of hilarity for me with some of their
additions to the set of archive formats, with things like hibernate
archives and service archives. These were good ideas, really, and
it's sad that I lacked the forethought to appreciate them. Mea
culpa.