Skip to content

System Design

Cleary, Paul edited this page Nov 9, 2015 · 1 revision

Core Concepts

At the core of Money is the concepts of a Span. A Span is construct that represents a group of related computations, Notes about those computations, and the duration required to complete those computations. Notes can be basically any relevant information about the Span, but most commonly they are durations. An example might be a Span representing computations required for a server component to complete an HTTP call to another server component. The Span may contain a note for the HTTP status code of the request, how long it took to retrieve the first byte of the response, how long it took to receive the entire response body, and how long it took to parse the response.

Spans can be arranged in a causal tree hierarchy which we will call a Trace. Each Span will be uniquely identified by three values: a unique SpanId that is generated for each Span on creation, a ParentSpanId denoting the Span that casually preceded it, and a TraceId denoting the first or root Span in the hierarchy.

Example Trace

In a system composed of a cluster of components responsible for Presenting a web page to end users, a cluster of components responsible for exposing a uniform API for the Presentation components, and cluster of components acting as a Data Store. Requests would be made of the Presentation component which would in turn make (possibly) concurrent requests of the API component, finally resulting in more (possibly concurrent) requests to the Data Store component.

A Trace and its associated Spans representing this chain of requests might look like:

If each component in the system had a mechanism to keep track of a Span for its own computations, we would be able to build up the Trace by aggregating Span data captured by each component. Money provides this ability. Spans are captured in log files, which can be aggregated and indexed and made available for search by a system like Splunk. Also Money emits span data to Graphite where dashboards can provide near real time metric analysis.

Money provides the ability to easily capture, track and emit Trace and Span data to log files and to Graphite. With that data ingested and aggregated, it will now be possible to understand the complex interactions between distributed components.

Dependencies

Money is designed to try and stay very lightweight. To that end, we limit our dependencies as much as possible.
You should NEVER add other dependencies to the money-core module.

Here are the dependencies that are in use:

  • scala - the whole thing is done in Scala, so yea, we need it
  • akka - the basis for the design is to use Actors for concurrency, so we make generous use of Actors
  • ficus - provides a scala wrapper around the typesafe config library (also, we use typsafe config for all configuration)
  • aspectj - this is not used by money-core, only used by some modules that provide aspects to make it simpler to use money

Scala and Akka provide extremely robust libraries for doing almost anything. Most likely, what you need is already there.

Scala also provides a ton of nice language features, so it is likely that you can create your own thing with very little code by just using Scala

Akka FTW!

Money is designed specifically to be able to handle the large volume of data that comes with doing distributed tracing.
To support this requirement, we make extensive use of Akka and Actors as the plumbing that sits underneath the money API.

Configuration

Configuration is built on the Typesafe Config Library. We follow the recommendations of typesafe for building our configuration, namely:

  • Default configuration is provided in a reference.conf file that lives in each deliverable in src/main/resources.
    Make sure that you provide a default configuration for all configuration entries that exist in the system, lest we avoid nasty NPEs and other run-time oddities
  • Overrides are provided in a file named application.conf that consumers of the library will implement themselves.