Six Considerations When Building High-Performance Java Microservices With EDA

Event-Driven Architecture (EDA) is a design principle focused on the creation, detection, and reaction to events. Renowned for its resilience and low latency, EDA is a reliable choice for developing robust, high-performing microservices. Moreover, this method can be helpful in improving productivity and making the process of cloud migration smoother.

EDAIn this article, we will outline six key considerations and tactics for developing such services.

Building Custom Solutions vs. Buy-and-Build Software

The Challenges of Building a FIX Protocol

The first day I was introduced to FIX was when I worked at an investment bank in London as a developer, I was told to write a feed handler to retrieve market data. Bear in mind that at this time, I knew nothing about FIX, apart from googling it for about 10 mins on the internet. With a touch of overconfidence and slight arrogance, I set to work coding a direct socket connection to the remote FIX endpoint, thinking, “How hard could it be?”

So, What Is FIX? 

Financial Information eXchange (FIX) is both a market data format and a protocol: it is used by investment banks to place orders and receive market data and has become a global language in financial trading. The format of a FIX message controls how it is encoded. All FIX messages start with 8=FIX, which denotes the start of a FIX message. They then go on to list key and value pairs. The keys are represented as numbers (known as TagNumbers) followed by a = delimiter to delimit the values. Each key=value combination is then delimited by the \u0001 character, which is sometimes visually represented as either ^ or |. The value is often written in a semi-human-readable format. I say semi-human readable because most of the time it is human-readable, but all too often, FIX will use a single character to denote a state or type of message. These characters are not always that obvious. I agree that the character B for "Buy" and S for "Sell" makes sense, but other characters are used that make no sense. For example, D denotes a "New Order Single" message, which is a message that is often used when you wish to place an order with your counterparty. 

Java: Why Core-to-Core Latency Matters

Last year we had a global shortage of microchips; today, I feel there is a worldwide shortage of software developers. Like many other software companies, Chronicle Software is rapidly expanding and interviewing candidates. We usually ask candidates to demonstrate a good knowledge of core Java, and then we cover slightly more advanced concepts, such as the use of volatile memory, memory barriers, and fences. While it is important to have a high-level understanding of these concepts when writing concurrent code, it's surprising how few Java developers with 10+ years of experience have a deep knowledge of the underlying hardware. An initial goal of Java was to “write once, run anywhere,” but does that mean we should not be sympathetic to the hardware? 

Java has done an excellent job at shielding developers from their platform; it is not unreasonable that most developers would rather solve their business problems than become overly burdened with the internal workings of their silicon. However, some sectors, such as fintech, benefit from fast software with predictable latencies, where every last microsecond can make a massive difference to their bottom line. For these sectors, it can be beneficial to have a reasonable grasp of the underlying hardware and basic knowledge of the areas described in the following sections.

How to Leverage Method Chaining To Add Smart Message Routing in Java

We are going to use the open-source serialization library Chronicle Wire. Let's assume we have some data that we want to send to a particular destination; we don't want to pollute our business data structures with the routing information. In the future, the routing information could be removed or changed based on external factors such as system failover or horizontal scaling.  

 Having a separation of routing and business messages is nothing new; after all, JMS has been doing it for years with their createObjectMessage (below): 

Challenges When Developing a GUI for FIX

This article explores the challenges in developing a graphical user interface (GUI) for Financial Information eXchange (FIX) data. FIX is both a protocol and a message format, but to create a FIX GUI we will focus just on the message format. A FIX message is a standard message format for transmitting financial and investment banking data.

Below is an example of a FIX message:

Why the Cool Kids Use Event Loops

When I was working in software development back in the 1990s, nearly all the software libraries that I worked on made use of event loops. This was because at the time most hardware had just one single CPU. Back in the day, I remember the excitement when threads were introduced into our development framework. It was revolutionary that we could now run two things at once, or rather appear to run two things at once, since a lot of the hardware at that time still only had a single core, and hence our threaded code was never really truly concurrent.

Over the years I've had mixed feelings about threads. Some of the most challenging systems that I’ve maintained have suffered from the overuse or misunderstood impact of concurrency. Even today I have discussions around if a piece of code is truly thread-safe and although the libraries (for example, the Java Concurrency Library) have made massive improvements reducing the burden of developing with threads, it is still somewhat of a challenge to ensure that we are not calling code which is not thread-safe when we have assumed it is. This is something that is generally not easily picked up by either static analysis or software compilers.

How to Develop Event-Driven Architectures

Last month, I wrote an article on open-source Chronicle Wire that discusses how we could serialize an application’s state into different message formats.

Now in this article, I'm going to look at how we can use open-source Chronicle Queue and Chronicle Wire to structure applications to use event-driven architecture (EDA). EDA is a design pattern in which decoupled components (often microservices) can asynchronously publish and subscribe to events. 

High-Performance Java Serialization to Different Formats

Java serialization is a popular mechanism where you are able to serialize and deserialize complex object graphs; for example where object A can contain a reference to object B, which in turn has a reference back to object A. The problem is that this rich functionality comes at a performance cost. However, if you do not need to serialize these types of recursive graphs, you can instead use an Open Source solution called Chronicle Wire. It has reduced complexity and uses tree-like structures which makes it very efficient. Moreover, it can be done in a lot of different formats with no need to change the coding. This article covers the basics of serialization and discusses some of the key advantages of Chronicle Wire.

Serialization and Deserialization

Serialization is about encoding java objects into bytes, for example, we have an object. Let’s say our object holds our application state, if we were to shut down our application we would lose the state, we want to first store our application's state to disk, so we serialize our java state object. This will convert the object into bytes, which can be easily stored.  Likewise, If we want to send the data stored in our java object, over the network, we first have to serialize the object, before it can be written to the TCP/IP buffer. Deserialization is the opposite of serialization, where we start with a byte and recreate an object instance.