I've had this post on my mind for some time now, and I think I finally have organized my thoughts.
Synchronous computation is an anachronism
In this day and age smartphones don't sit there waiting for data to come back. They are expected to be turned on and off at random. When they are on users expect to access their information immediately. Smartphones need to manage their power. Implemented properly, applications push their data to mobile devices, rather than the other way around. Even taking mobile devices aside, as a general rule users expect their data to be updated without having to refresh their views.
Multiple core CPUs are the norm these days, and not just on high powered equipment. On a more technical level, synchronous computing in a concurrent environment introduces concurrency bottlenecks and lock synchronization complexities.
So now we agree that we should all strive towards asynchronous computing models. It is not as complicated as it may seem. The requirement is merely to think in terms of a functional rather than procedural way of thinking. All computation is a function. Output of each function only depends on its inputs. All functions are stateless. If we pretend that there is a pool of modules that can calculate a particular function, then each module should return the same result as all others.
Messaging is an approach to asynchronous computing
A messaging architecture such as JMS (in case of Java) provides a convenient integration layer between modules. Modules can exist on different pieces of hardware in different geographic locations. Modules can be written in different languages and don't need to be aware of each other's location. This results in a scalable model where messaging acts as a workload distribution layer between modules, and work can be divided into independent chunks.
Messaging can act as a coordination layer between modules where redundancy is expected. Primary and hot standby backup can be coordinated with messaging. Modules can be brought online seamlessly and can automatically discover one another be aware of each other's status.
As a general rule anything that can be done with RMI, EJB, CORBA, etc. can be done much simpler with messaging. In fact, in my humble opinion, JMS should always be picked over any other distributed computing technology available in Java.
Types of messaging
In a publish-subscribe scenario there are many publishers publishing on a single topic. There are many subscribers that expect messages to arrive on that topic. All of them get the message at the same time. A good example of such configuration is market data distribution, where all participants expect to get the same exact data at the same exact time.
In a point-to-point scenario there also many publishers and many subscribers. Instead of a topic there is a queue. Publishers put messages onto the queue. Only one subscriber at a time gets the message. Thus, messaging takes care of load balance. A good example of this scenario is asynchronous delivery of data into a data store, or load balancing calculations.
One last scenario is inboxes or temporary queues. Participants establish private temporary channels to exchange messages no other participant should care for. This often goes hand in hand with point-to-point messaging to return results of calculations back to the publisher.
Messaging topologies
With In-process topology all messaging happens within the process. This facilitates asynchronous computation within a single module. Components are decoupled from one another and all interaction between them happens via messaging. This is suitable for relatively simple systems but paves the way for further scaling if the workload exceeds capacity of a single machine.
Participants may also connect to a single external broker server in a hub and spoke topology. The broker does the job of delivering messages to each consumer. This is best suitable for point to point messaging and is counter productive for publish-subscribe. In the latter scenario the broker would have to deliver the same exact message over the same network interface multiple times and none would be guaranteed to get data at the same exact time.
In a Multicast topology multiple brokers exist on the network. Participants discover brokers via IP multicast. All brokers get all messages, hopefully at the same time (hardware permitting), and deliver them to participants. This is best suited for publish-subscribe but doesn't work well for point-to-point (why bother all brokers with messages aimed at only one).
Many applications involve both P2P and pub/sub messaging, so a decision must be made on a case by case basis which topology to set up. With the right choice of messaging system, this decision can be made at a later date as the system grows. Many systems (ActiveMQ, Tibco) allow for router and broker configuration that doesn't impact the application code. With the right choice of messaging platform your application can take advantage of modern architectures and grow as your needs scale.