FastQuote Architecture

Overview

FastQuote is a low-latency trading application that demonstrates how to build high-performance services with Fabric3. It consists of a liquidity provider runtime that acts as the source of currency price feeds (a third-party bank or exchange) and a price engine run by a bank, FastQuote, that is responsible for subscribing to those feeds and margining prices. The margined prices are in turn published to FastQuote customers who trade currency. The following diagram illustrates the trading system setup: 

FastQuote demonstrates a number of key features:

  • High Performance Services: SOA is not just about HTTP and Web Services (WS-* or REST). Fabric3 integrates with a number of high-performance libraries including ZeroMQ, the LMAX DisruptorJava Chronicle, and Protocol Buffers.
  • Modularity: Build highly modular systems with zero impact on performance. Fabric3 can optimize cross-module service invocations to by-reference intra-VM calls. 
  • Non-Intrusive Middleware: Fabric3 takes advantage of a number of optimizations to avoid runtime overhead and excess garbage creation. For example, Fabric3 supports dynamic bytecode generation in place of JDK proxies so that service invocations and message publishing are done as fast as hand-written code with no object creation.
  • Simplicity: Fabric3 greatly simplifies event-sourced architectures by removing boilerplate and low-level API calls from application code.    

System Architecture

The Price Engine is the core of the FasQuote trading platform. It is best described as an event sourced architecture consisting of a number of modules that handle various pricing functions. The aggregation module receives incoming price streams from one or more liquidity providers. Aggregation passes price events to the pricing module, which is responsible for margining. The pricing module in turn calls the publishing module to distribute margined prices to FastQuote customers. The following diagram illustrates the Price Engine modules and services: 

It is important to note that the Price Engine is a single process and all business logic executes on one thread. Note only does this architecture make development simpler (testing and profiling can be performed against a single JVM), but it is also more performant than highly distributed systems. Collocating the subsystems removes the overhead of serialization and network hops. Running application logic on a single thread allows lock-free data structures that avoid contention, removes context-switching overhead, and provides CPU cache-friendly processing. This architecture is possible since bottlenecks are typically at the edges of the system and not in the application logic. That is, bottlenecks are commonly the result of reading and writing messages over a remote transport.

It is worth highlighting that the FastQuote architecture also supports high availability. As prices are read from the incoming liquidity provider stream, they are replicated to warm backups.

Modularity

When examining the source code, you will notice that the FastQuote subsystems (e.g. aggregation, pricing, and publishing) are decomposed as Maven modules. Each subsystem has an API module and an implementation module. The API modules are used by client modules to pass prices for further processing. API module dependencies are managed using OSGi import/export directives (for more information, see Contribution Modularity). For example, the aggregation implementation module imports the pricing API module, which contains the PricingService interface. Note that even though the subsystems are contained in separate modules, at runtime Fabric3 will optimize wires between the services to be by-reference calls. This means that modularity incurs no runtime invocation overhead.