How does Ice compare with MQ Series?

The glib answer to this question is, "It doesn't."

A more detailed answer needs to look at what Ice and MQ Series have in common. As it turns out, they have almost nothing in common. While either technology can be used to build distributed systems, that is pretty much where the similarities end.

MQ Series is fundamentally a store-and-forward technology. Producers send messages to a queue that accepts and stores the messages. The queue, in turn, stores the messages until consumers retrieve them. Queues have persistent storage for messages, which allows the producer of a message to send a message even if the eventual consumer is currently not running; the queue will deliver the message later, once the consumer is back up again. MQ Series provides transactional semantics, which means that messages are delivered with guaranteed exactly-once semantics.

Message queues are unidirectional, that is, if a consumer wants to send results back to a producer, it must become a producer and send a separate message via a separate queue to the original producer, which now becomes a consumer of the result message.

MQ Series limits messages to a handful of built-in types, such as simple numeric types and strings. If you want to transmit complex types, such as structures, sequences, or graphs of objects, you must define your own serialization format and provide code that is called by the queue to unmarshal your data. Depending on the type of data, you are also responsible for chores such as character codeset conversion and byte swapping.

In contrast, Ice is an object-oriented RPC technology. In essence, it allows you to create objects in your favorite programming language, and to have clients invoke operations on these objects with the usual object-oriented semantics: Ice objects support dynamic binding (that is, an operation invoked on a base type is dispatched to an implementation that possibly has a more derived type) and the Liskov substitution principle (that is, a more derived type can be passed where a base type is expected). Clients and the Ice objects they invoke operations on can reside in different address spaces and, at the API level, an invocation on an Ice object looks very much like an invocation on an ordinary, language-native object. However, for clients to successfully invoke an operation on an Ice object, at least one of the servers implementing that object must be reachable to the client, because Ice does not provide store-and-forward invocations.

Ice permits you to transmit complex data types, such as structures, dictionaries, and arbitrary graphs of classes without having to involve yourself with issues such as encodings and marshaling rules.

In summary, Ice makes distributed programming largely transparent because it retains as much of the usual object-oriented semantics as possible. Remote invocations look and feel like local ones, operations can return results and report errors via exceptions, and the client need not know the location at which an object's server resides.

The approaches taken by MQ Series and Ice are very different, and the way you need to design an application using each technology is also very different. Because MQ messages are unidirectional, an application using MQ Series has to be designed to that limitation. (The Ice equivalent of this would be to disallow out-parameters, return value, and user exceptions for all operations, that is, to make all operations callable as oneway operations.) Obviously, the interfaces and client–server interactions of an application limited in this way are very different than those of an application that is not: MQ Series clients cannot simply invoke an operation, wait for the operation to complete, and then process the results. Instead, they need to be written much like an event driven program.

So, comparing MQ Series and Ice is a little like comparing apples and oranges. Because the respective communication paradigms are so different, there really is no comparison that would be all that meaningful. If you really need to choose between the two technologies, the best advice we can give is to check whether your application requires that clients be able to send messages even when servers are down or unreachable. (Note that this does not necessarily mean that a client can send messages when it is completely disconnected; this is possible only if the message queue runs on the same machine as the client.) If so, MQ Series might be a good candidate for your application.

On the other hand, if your application does not have such a requirement, MQ Series extracts quite a high price because it forces you to design to a communications paradigm that most programmers are unfamiliar with, and that is very different from the APIs provided by existing libraries and services. In that case, Ice is probably a better match for your application than MQ Series.

See Also