The challenges of scaling microservices

IT is being driven by DevOps and containers across many organizations. These twin trends are part of a larger shift in IT called microservices—breaking down the traditional monolithic approach to IT and software development into much smaller, more manageable components.

Scaling to meet demand is a significant issue for any IT deployment, though, and microservices are no exception. So before you dive into the deep end with microservices, you should understand what challenges you might face and how to overcome them.

Testing in the Agile Era: Top Tools and Processes

What are microservices?

Before we start talking about how to deal with the challenges of scaling microservices, let's talk about what microservices are. I generally refer to Wikipedia because I appreciate that the information is crowdsourced, so whatever the Wikipedia entry states is a sort of consensus definition. It's particularly useful for cutting-edge or emerging concepts like microservices. Wikipedia defines microservices as "...a software architecture style in which complex applications are composed of small, independent processes communicating with each other using language-agnostic APIs. These services are small, highly decoupled and focus on doing a small task, facilitating a modular approach to system-building."

Al Hilwa, program director of application development software at IDC, describes it this way: "Microservices is an architectural approach that draws on long, evolving experience in software engineering and system design, including the SOA efforts of the last two decades. Microservices architecture is enabled by a spectrum of tool categories, but is primarily an architectural approach to system design that also requires considerable organizational and cultural adjustment to execute successfully."

More succinctly, microservices is a blanket term that applies to breaking IT systems and applications down to smaller, more granular elements. Containers take applications and services down to a self-contained, component level, and DevOps provides the framework for the IT infrastructure and automation to develop, deploy, and manage the environment.

Jason Bloomberg, president of Intellyx, talks about the distinction between a typical web service and a microservice, arguing against the tendency to try to simply rebrand web services as microservices. "A microservice, in contrast, is a parsimonious, cohesive unit of execution. It's decidedly not a software interface itself, although it obviously has one. Instead, at the heart of the microservice is the running code itself. Microservices also contain their own runtime, so they don't need to run on an ESB [enterprise service bus]."

Microservices deliver macro benefits

Hilwa says, "Microservices are typically developed with modern elastic and often stateless back-end architectures, but that does not mean they are automatically scalable. Architects have to take special care to make sure that centralized services or databases are also designed to be scalable. Microservices also put a lot of pressure on APIs, highlighting the importance of strong API management technology in the software stack being employed."

The very nature of DevOps and containers make them inherently more scalable than a traditional IT infrastructure—especially an infrastructure of physical servers in an on-premise data center. The foundation of microservices is built on the cloud and virtualization, both of which include scalability as a core feature. Virtualization enables servers to be created and provisioned at the push of a button as demand spikes, and simply turned off and deleted when the need subsides.

The same thing is true for containers. Containers are self-contained components that can be easily duplicated and expanded as demand increases. New instances of containers can be created automatically or programmatically to scale with demand.

Bloomberg cautions, "Microservices don't require containers (or vice versa), but they're easily containerizable by design. Furthermore, if you're implementing containers, it's difficult and typically unwise to put any new executable code other than microservices in them."

Microservices, DevOps, and containers are all inherently more scalable than legacy IT infrastructure and app development models, but there are still challenges to address. You still have similar concerns in terms of scalability, but the approach to scaling is different when you're dealing with microservices.

The scalability cube

The Art of Scalability by Martin L. Abbott and Michael T. Fisher describes scalability using a cube model. The "Scale Cube" is composed of an X-axis, Y-axis, and Z-axis. The traditional method of scaling by running multiple copies of an application load-balanced across servers is the X-axis.

The general approach of microservices falls along the Y-axis. Y-axis scaling breaks the application into its components and services. Software architect Chris Richardson explained this method in a blog post: "Each service is responsible for one or more closely related functions. There are a couple of different ways of decomposing the application into services. One approach is to use verb-based decomposition and define services that implement a single use case such as checkout. The other option is to decompose the application by noun and create services responsible for all operations related to a particular entity such as customer management. An application might use a combination of verb-based and noun-based decomposition."

That leaves the Z-axis. The X-axis is traditional load-balance scaling, and the Y-axis is embracing microservices. The Z-axis takes a similar approach to the X-axis—running identical copies of code across multiple servers. What makes Z-axis scaling unique is that it also borrows a page from the Y-axis, so each server is only responsible for a subset of the application rather than the application as a whole.

Scaling microservices

Now let's put that all together. There will still be spikes in demand and a need for scalability with microservices, just as there are with a traditional IT infrastructure and app deployment. Because the app itself is broken down into smaller components that may or may not be spread across separate servers, you have to approach scalability a little differently.

The benefits of microservices notwithstanding, there's an added level of complexity when it comes to scalability. Instead of dealing with a single application running on a single server—or load-balanced across a few servers—you might have elements of an application written in different programming languages, loaded on different hardware, running on different virtualization hypervisors, and deployed across disparate cloud and on-premise locations. When demand increases for the app, all the underlying components have to be coordinated to scale, or you have to be able to identify which individual elements need to scale to address the surge in demand.

Using the Z-axis scaling approach from the Scale Cube allows you to segregate data across different servers based on routing criteria. You might route requests based on the primary key of the data being accessed, or based on customer type—sending paying or premium customers to servers with more bandwidth and capacity to deliver better performance.

With the legacy approach to IT infrastructure and app deployment the whole app had to be addressed as a monolithic entity. If demand spiked, the whole application had to be multiplied to accommodate the load, which meant multiplying the servers or virtual server instances on which the application was running.

With microservices, everything is more granular, including scalability and managing spikes in demand. Demand may surge for one component of an app or a certain subset of data, and a microservices architecture enables you to scale only the app components impacted, rather than the entire application and underlying infrastructure.

Performance matters

No matter how you view the challenges of scalability for microservices, from the customer or end-user perspective, what matters is the performance of the app itself. From that perspective, it makes sense to use some sort of app proxy or application deliver controller (ADC) as an intermediary to detect issues with performance and facilitate the automation of scaling when necessary.

Traditional ADCs approach the issue from a one-to-one perspective, though. They're optimized to manage applications that exist on a single hardware platform running in a single location. Microservices change that relationship so that it requires an ADC that's microservices-aware. You need an ADC that can monitor and deliver consistent app performance in a way that is location- and platform-agnostic.

Article Tags