The dark side

The Dark Side

Microservice architectures are not all rainbows and unicorns. Beyond all the hype and hyperbole microservices are just distributed systems, and distributed systems are hard. With distributed systems, we are increasing the operational complexity of an application by splitting it into multiple independent processes. Each service process has its own management, lifecycle, and failures. When building microservices, it is critical to remember the well-worn engineering aphorism known as Murphy's Law:

"Anything that can go wrong, will go wrong."
-- Murphy's Law

If that isn't depressing enough, Murphy's Law can be further specialized for distributed computing. A list of these came out of Sun Microsystems in the 1990s and are known as The Fallacies of Distributed Computing. The first seven of these are generally attributed to L. Peter Deutsch, Bill Joy, and Tom Lyon. The eighth was added by James Gosling in 1997.

The Fallacies of Distributed Computing

  • The network is reliable

    It's a safe bet that the network will go down at some point. All it takes is a brief power cycle, a cable-cut or simply someone disconnecting your network switch to cause a network outage. Every networking device has a MTBF rating- which is declare the device's Mean Time Between Failure. This fact alone undermines this fallacy and makes it crucial that all network-related calls trap and mitigate network errors.

  • Latency is zero.

    Latency is the time it takes data to move between two points. Latency includes signal propagation delay (which increases as a function of distance) and congestion delay (high network traffic volumes reduce the speed in which networks can pass messages). Together, these two values will always be a non-zero sum. When designing services, it is essential to realize that a chatty interchange between services will degrade the operation of the overall application.

  • Bandwidth is infinite.

    Bandwidth is the capacity of a network to transfer data for a given interval. A simple analogy can be found with the comparison of a garden hose and firehose. The garden hose has significantly less capacity to transfer water. In a communication network, a mobile device connection to the public API of an application has less bandwidth than the inter-service bandwidth in a data center. For every networking environment, there is an upper bound on its carrying capacity. When designing microservices, we should always seek to minimize the amount of data passed between services. By transmitting only essential data we lower both the serialization cost of the data and the transmission time between services. A reduction in transmitted data also reduces network congestions which degrades communication throughput.

  • The network is secure.

    The only secure system is one that isn't connected to a network (theoretically). Every system is only as secure as its weakest link. A secure system needs a multilayer approach including security at the network, infrastructure, and application level. Microservices can have a wider attack surface than a traditional monolithic application due to their distributed nature, so it is even more important to pay attention to security requirements when implementing microservices.

  • Topology doesn't change.

    Any time you connect or disconnection a new laptop to your network the network topology changes. Servers, routers, and switches fail. Each failure brings a network topology change. Always assume that the device you are trying to reach may be unavailable. Network topology changes are especially pronounced in an elastic microservice architecture where services are continually being brought online and taken out of service in response to load. Avoid depending on static addressing as much as is practical. Rely on DNS, Service Discovery patterns and Asynchronous messaging to avoid static addressing.

  • There is one administrator.

    Never assume that there is a single entity who knows everything about the application and the network it is running on. If you discover that there is only one omnipotent administrator, consider getting them a backup in case they are struck by a meteorite. In a microservice architecture, there will rarely be a single administrator responsible for the entire application. Instead, expect that each service may have a handful of people responsible for its administration. Consider this a strength and embrace it.

  • Transport cost is zero.

    There are two types of transport costs. The first cost to be aware of is the application performance cost due to the serialization and deserialization of data. Only transfer essential data. This is important to consider between the client and application where the bandwidth is lowest as well as between services where the frequency of service calls is the highest. The second cost is financial cost. These include the asset cost of the networking infrastructure (e.g., hardware, administration, etc. ) as well as cost incurred by telecommunications service providers (internet providers) and cloud provider platforms. While cloud platforms are generally cheaper and more flexible than managing your own data center, there is a cost to spin up load-balancers and clusters of virtual machines and containers. There is also a cost when moving data into and out of the cloud. Some cloud providers may charge when moving data between cloud regions, so it is prudent to be aware of these financial costs.

  • The network is homogeneous.

    There is a good chance you know very little about the nature of the clients who are connecting to your application. It should be expected that they will be running many different types of hardware running different versions of different operating systems. With this in mind, it is important that each service communicates with its client using standard protocols (e.g., HTTP, JSON, XML, etc.).
Beyond these concerns, there is the additional operational overhead that comes with distributed systems, including deployment & monitoring. Over time the application may come to depend on different versions of the same service running in production. This parallel deployment may be necessary until the older service versions are sunsetted and can be safely decommissioned. This multi-version service deployment approach will increase resource utilization and management costs.

So when building microservices, it is always important to remember:


Summary

With microservice architectures, we must acknowledge that there are tradeoffs between architectures. To achieve the required application autonomy, isolation, and scaling goals we must incur the costs associated with distributed systems- added complexity and eventual consistency.

Microservices are hard to compete with when you need a truly resilient, responsive, hyperscale application. However, it is important to understand that with great power comes great responsibility.

Coming up

Now it's time to take your understanding to the next level. In our next post, we will address the three-legged beast known as CAP Theorem.