RPC (Remote Procedure Call) is a term commonly used to describe a distributed computing model that is used today by middleware technologies such as CORBA, Java RMI, and Microsoft's DCOM. Component-based architectures such as Enterprise JavaBeans are built on top of this model. RPC-based technologies have been, and will continue to be, a viable solution for many applications. However, the enterprise messaging model is superior in certain types of distributed applications. In this section we will discuss the pros and cons of each model. In Chapter 8, J2EE, EJB, and JMS, we will discuss a means of combining the two.
One of the most successful areas of the tightly coupled RPC model has been in building 3-tier, or n -tier applications. In this model, a presentation layer (1st tier), communicates using RPC with business logic on the middle tier (2nd tier), which accesses data housed on the back end (3rd tier). Sun Microsystems' J2EE platform and Microsoft's DNA are the most modern examples of this architecture.
With J2EE, JSP and Servlets represent the presentation tier while Enterprise JavaBeans is the middle tier. Microsoft's DNA is architecturally similar to J2EE, relying on ASP for presentation and COM+ for the middle tier. Regardless of the platform, the core technology used in these systems is RPC-based middleware. Whether it's the EJB or COM+, RPC is the defining communication paradigm.
RPC attempts to mimic the behavior of a system that runs in one process. When a remote procedure is invoked, the caller is blocked until the procedure completes and returns control to the caller. This synchronized model allows the developer to view the system as if it runs in one process. Work is performed sequentially, ensuring that tasks are completed in a predefined order. The synchronized nature of RPC tightly couples the client (the software making the call) to the server (the software servicing the call). The client cannot proceed—it is blocked—until the server responds.
The tightly coupled nature of RPC creates highly interdependent systems where a failure on one system has an immediate and debilitating impact on other systems. In J2EE, for example, the EJB server must be functioning properly if the servlets that use enterprise beans are expected to function.
RPC works well in many scenarios, but its synchronous, tightly coupled nature is a severe handicap in system-to-system processing where vertical applications are integrated together. In system-to-system scenarios, the lines of communication between vertical systems are many and multidirectional, as Figure 1.8 illustrates.
Consider the challenge of implementing this infrastructure using a tightly coupled RPC mechanism. There is the many-to-many problem of managing the connections between these systems. When you add another application to the mix, you have to go back and let all the other systems know about it. Also, systems can crash. Scheduled downtimes need to happen. Object interfaces need to be upgraded.
When one part of the system goes down, everything halts. When you post an order to an order entry system, it needs to make a synchronous call to each of the other systems. This causes the order entry system to block and wait until each system is finished processing the order.
It is the synchronized, tightly coupled, interdependent nature of RPC systems that cause entire systems to fail as a result of failures in subsystems. When the tightly coupled nature of RPC is not appropriate, as in system-to-system scenarios, messaging provides an alternative.
Problems with the availability of subsystems are not an issue with Message-Oriented Middleware. A fundamental concept of MOM is that communication between applications is intended to be asynchronous. Code that is written to connect the pieces together assumes there is a one-way message that requires no immediate response from another application. In other words, there is no blocking. Once a message is sent, the messaging client can move on to other tasks; it doesn't have to wait for a response. This is the major difference between RPC and asynchronous messaging, and is critical to understanding the advantages offered by MOM systems.
In an asynchronous messaging system, each subsystem (Accounts Receivable, Inventory, etc.) is decoupled from the other systems (see Figure 1.9). They communicate through the messaging server, so that a failure in one does not impede the operation of the others.
Figure 1.9. JMS provides a loosely coupled environment where partial failure of system components does not impede overall system availability
Partial failure in a networked system is a fact of life. One of the systems may have an unpredictable failure or need to be shut down at some time during its continuous operation. This can be further magnified by geographic dispersion of in-house and partner systems. In recognition of this, JMS provides guaranteed delivery , which ensures that intended consumers will eventually receive a message even if partial failure occurs.
Guaranteed delivery uses a store-and-forward mechanism, which means that the underlying message server will write the incoming messages out to a persistent store if the intended consumers are not currently available. When the receiving applications become available at a later time, the store-and-forward mechanism will deliver all of the messages that the consumers missed while unavailable (see Figure 1.10).
To summarize, JMS is not just another event service. It was designed to cover a broad range of enterprise applications, including EAI, B2B, push models, etc. Through asynchronous processing, store-and-forward, and guaranteed delivery, it provides high availability capabilities to keep business applications in continuous operation with uninterrupted service. It offers flexibility of integration by providing publish-and-subscribe and point-to-point functionality. Through location transparency and administrative control, it allows for a robust, service-based architecture. And most importantly, it is extremely easy to learn and use. In the next chapter we will take a look at how simple it is by building our first JMS application.
 Multithreading and looser RPC mechanisms like CORBA's one-way call are options, but these solutions have their own complexities and require very sophisticated development. Threads are expensive when not used wisely, and CORBA one-way calls still require application-level error handling for failure conditions.