I enjoyed the book and think that it expanded my ideas about message queuing and its implementations.
My Background: I currently support a CM system that is used to support multi-project COBOL, and other language, compilations. I am also familiar with writing and compiling C, C++ and other language programs on various platforms, using a variety of approaches including OO and handcrafted messaging. A number of my colleagues work as EAI specialists and some make use of message queuing technologies in their work areas and I have always wanted to know more. This book's appearance in the book list seemed an excellent opportunity to find out more about how MSMQ and MQSeries work.
In a distributed programming environment there are a number of ways for programs that need to share data across a network to communicate.
The first is Remote Procedure Call (RPC) where a client program makes a network request for a piece of code, the remote procedure, to be executed on another machine, usually referred to as the server, in a synchronous way. In RPC environments the need to guard against, and recover from, network failures can make code extremely complex and, indeed, it may be impossible to recover from some types of error. Distributed object approaches such as DCOM, Java and CORBA are similarly affected where remote method invocation is employed.
The second approach involves Distributed Transaction Processing (DTP), like BEA's Tuxedo, IBM's Distributed CICS and Microsoft's MTS. This technology is often used in mainframe computing systems where reliability and the ability to recover from network errors is required, but DTP systems tend to be complex and expensive to install and maintain. Like RPC, DTP is a synchronous form of communication; so both the client and the server need to be running simultaneously.
The third approach is message queuing and it is the technologies that are provided by Microsoft (MSMQ) and IBM (MQSeries, hereafter MQS) that are discussed in this book (the author points out that there are other MQ providers but MSMQ and MQS have significantly higher installed bases). MQ is an asynchronous technology in so far as the client and server code need not be running simultaneously.
It is very common for business-wide applications to make use of facilities like message queuing. Many types of business transaction do not require synchronous communication - although, e.g., a 'debit account' transaction would usually need a) to be synchronous and b) not to be repeated after a network failure if the change had been applied. However some telephone banking systems use asynchronous account transfer transactions; you say when you want your account debited, where it is to go and the amount, then the system does the rest. The only feedback at the time of placing the transaction is confirmation of the transaction details, you need to check your account later to be sure if it has been processed correctly-- this type of transaction is often achieved using message queuing.
As to the book itself, it explains much of the above and a lot more besides. I liked the author's style and the fact that he explains the choices that he made in writing the book. For example, he explains that the code examples are in procedural C, but MQS and MSMQ both support other languages and design approaches (OO, say); he chose C because most programmers can read and understand procedural C, the same would not be true of some of the other options. I agree with his argument as it makes the text open to the widest possible audience.
All the code from the book is available via a www page, but the URL does not seem to be mentioned in the body of the text, although it is on the back cover of the book. The download is a self extracting archive of 428kb containing about 1.5Mb of source files, these have been produced with MS Visual C++ 5 and can be used directly from versions 5 or 6. As I do not have a copy of MSVC++ 5 or 6 I was not able to try the example code. Each segment of code is discussed in some detail in the book and I was glad to see that Que have taken note of previous comments and not included the code in appendices as well as in the body! The examples were designed and run on a Windows NT machine and some screen shots of the GUI and command line windows are used to illustrate the text.
In the first chapter the foundations of message queuing are explained with the differences between 'inquiry' and 'update' and 'asynchronous' and 'pseudosynchronous' transactions being discussed. A number of the high-level design issues are covered here along with brief discussion of possible problems that might cause transactions to fail.
The next two chapters discuss the code to implement an inquiry transaction, using a simple phone book database; chapter 2 uses MQS and chapter 3 MSMQ. The style of code is a very personal issue, but I found the examples easy to read and perfectly adequate as examples of how MQ is invoked. The chapters each start off with a simple version of the code for both the client and the server and then, after pointing out the flaws in the simple version, move on to modify the client and server code to make it more robust and secure. In this case the client will simply be expected to retry the inquiry if it fails - perhaps because the queue manager is shut down for a period; persistence of the message queue is not used.
Chapter four implements an asynchronous update transaction 'fire-and-forget' that modifies the server's in-memory data using MQS, but does not cover the updating of any form of persistent store. This is a sensible approach as it keeps the example simple and allows the author to concentrate on the MQ aspects without needing to introduce database specific components or code. The most important feature of this type of transaction is that the message queue is persistent; the queue manager can be stopped and started, but messages are retained, unlike the inquiry examples from the earlier chapters.
In the next chapter there is good coverage of transactions and their management together with examples using MSMQ and Microsoft's DTC (part of SQL Server); this describes the differences between DTP's need for synchronous communications and the ability of transactional messaging to permit some degree of asynchronous communication. This chapter also introduces the idea of splitting the server's processing ability into threads and using each thread to process a different type of queue; one inquiry type, the other an update. The design and development, using the COM components, is well analysed and almost complete - only omitting a few elements that would be required for a real application suite, in particular how 'poison messages' can be handled (these cause the server to loop indefinitely).
Chapter six uses the Open Group's XA interface to implement multithreading with MQS. This implementation is similar to the MSMQ version, but does discuss how to handle 'long running transactions' and 'poison messages'. This chapter contains a very obvious flaw - one of the diagrams is wrong; this is something that peer review should have identified.
Chapter seven discusses error handling&debugging; issues such as error logging, the passing of errors to different queues (there are some types of error that need compensating transactions to be run - these require the action of a second program via a message queue) and some means of dealing with messages that cannot be dealt with by the server application itself. The latter type of message is called a 'dead letter' and needs to be forwarded to a suitable queue for processing. Both MQS and MSMQ provide the ability to handle 'dead letters', but often a separate monitoring application is used to ensure that severe system errors are identified and corrected.
Chapter eight, in contrast to the earlier chapters that used the full server-side installation to build clients, looks at the client-side installation of MQ. In the server-side installation queues can be built on the client machine; in contrast the client-side version is more compact and needs to use the queuing mechanisms on a server. The main benefit of this approach is that the client-side software is more compact, cheaper and easier to maintain. Indeed, on many platforms client-side is the only available product and, in the case of MSMQ, is only available from vendors other than Microsoft. This chapter discusses how to set up clients for both products.
Chapter nine discusses connecting MQ systems together, including the connections to mainframe computers. It also looks at the connection of differing MQ systems via the MQS and MSMQ bridge and a brief look at EAI.
The book ends with two substantial appendices that respectively discuss the MQS and MSMQ APIs in some detail. These would be very useful as a reference for someone starting out with MQS or MSMQ. There is also a very detailed index; some would say too long, but I believe it is justified as it contains references to all the API components making it easy to use the book for reference purposes.
Rhys Lewis worked for IBM at Hursley as a developer for MQ Series and the book has been produced and reviewed in conjunction with MessageQ.com. I enjoyed the book and think that it expanded my ideas about message queuing and its implementations. I hope to move into a work-area using message queuing in the near future and this book has helped prepare me for this. There are some minor textual errors, but I did not notice anything obvious in the code examples.