Overview
Performance is vital in the world of stock trading, you can easily lose hundreds of thousands of dollars if the trading platform you’re using routes orders to the stock exchanges too slowly and you miss the your target price.
The order management system I work on uses IRC as the messaging middle ware– a message is sent to a channel and another process reads and processes the message. This gives us great flexibility, letting us write the user interface in .NET and the back-end server code in whichever language we choose and it also allows us to scale the system by moving processes to different machines.
But this setup has problems, if a message is missed by a process, there’s no easy to way to retrieve it and recent benchmarking showed that the latency of the messaging system spikes, unpredictably to 300 ms or more. Initially IRC made sense but the requirements have grown and it’s clear a more robust solution which provides greater reliability, performance and scalability is needed.
AMQP
The Advanced Message Queuing Protocol (AMQP) is an open standard, vendor neutral binary protocol for messaging middleware. AMQP features: messages, queuing and routing and it was designed by the financial industry to replace existing proprietary message queues. It seems to be the Promised Land—the perfect replacement for IRC.
After a quick evaluation of messaging brokers, the best candidates appear to be RabbitMQ and Apache Qpid. Both support AMQP, seem to have low latency and have vendor support—Qpid in the form of RedHat MRG. While both seem to be faster than IRC, I needed to be sure.
AMQP is more complicated than IRC and replacing the current messaging system won’t be easy. I wanted to create a benchmark that simulates the load we see in a production environment, but before I could create the test, I need to better understand what AMQP provides and the terminology it uses.
AMQP Features
Messages are glorified strings which are published to an exchange. They consist of a header and a content body, while headers have several properties; you only need to know one to get started: the routing-key, a field used by exchanges to determine which queue the message will be routed to.
Queues are where your messages wait until they are consumed. Queues can be configured to let messages die if a consumer is not available, queues along with exchanges can be made durable. Message can persists if the queue and the exchange are marked as durable and the message’s delivery mode is set to persistent.
Exchanges the help the broker decide which queue to route your message to. While they’re slated for removal in AMQP 1.0, but they’re still important and difficult to ignore– there are four types of exchanges: Fanout, Direct, Topic and Header.
- Direct exchange: Use routing keys, messages sent to a direct exchange are routed to exchanges where the routing key matches exactly.
- Topic exchange: A hierarchical exchange which also uses routing keys, routing keys are matched against a pattern, the hierarchy is established by separating keywords with the dot symbol.
- Fanout Exchange: A 1:N exchange, any message sent to an exchange is sent to all queues bound to that exchange.
A Channel is to AMQP what session is to HTTP, I’m not sure if that’s very accurate– all communication over a channel is stateful, and each instance of your program will have at least one channel.
Conclusion
There’s a lot to digest, I spent the better part of the day reading RabbitMQ’s .NET API Guide. In part two of this series I’ll walkthrough C# client and benchmark RabbitMQ. As always, your feedback and comments are appreciated.
Related posts:





I really like this blog good job.
Odette - 30 Aug 09 at 11:07 pm