BACKGROUND IMAGE: stock.adobe.com
Instead of writing applications that comprise thousands of lines of integrated code, we now routinely break applications into components in order to easily distribute work to a team of developers, facilitate the reuse of common logic, and promote resiliency and scalability. Components that are separately hosted rather than integrated into a machine image are typically called services -- but not all services are the same.
The fusion of the internet and online transaction processing (OLTP) has shaped how software components get defined as either stateless or stateful microservices or serverless functions.
Application design, OLTP and state
Many everyday acts involve OLTP, such as bank withdrawals, in-store purchases and even online orders. OLTP is an electronic pathway for business activity that replaced paper receipts and invoices. At a high level, OLTP represents a stateful interaction. For example, bank withdrawals exhibit continued state behavior over multiple steps, as the available balance is reduced after you take money from your account.
But stateful behavior isn't the only option. Many applications on the internet use an approach that treats every request as a stand-alone unit, without context or state. These are known as stateless interactions.
An application's stateless components can be replaced if something breaks, and there's no impact because nothing ever saves within the old copy. Stateless apps can also scale because any instance can run a request and get the same result. In theory, they're perfect for cloud application architectures.
However, keep in mind what would happen if you had stateless OLTP for bank withdrawals; the transaction wouldn't actually decrease your balance because no specific state is ever reflected with the request.
The fundamental dilemma of cloud application design is that business typically runs on stateful functions, but the cloud works best with stateless components. This dilemma even impacts the foundational concept of microservices, which focuses on creating reusable components designed for elastic deployment in the cloud. Some microservice definitions mandate stateless behavior, while others require stateful behavior. These contrasting definitions must find a way to harmonize with the reality of OLTP or else the cloud won't be able to optimally support business activities.
Stateless vs. stateful microservices
The storefront design pattern represents an OLTP vision of microservices. It consists of a single online portal that offers a variety of retail services, each represented by a separate software component. Because retail activity is inherently stateful, the pattern dictates stateful microservices. If one of the retail microservices breaks or if the workloads demand scaling, software teams must be prepared to adjust the stateful behavior of the components.
This type of adjustment involves stateful load balancing and distributed transaction processing techniques to manage scaling. It also requires a two-phase commit, which is a standardized protocol that makes sure a database commit carries through when a commit operation breaks into two parts.
In the cloud microservices approach, a microservice acts as a stateless function -- also called a lambda function, and its outputs always depend on its inputs only. Because nothing is ever stored in a stateless microservice, any copy serves equally, so any copy can replace a failed copy without impacting any work in progress.
Literature for Google's cloud service uses the term microservices to describe what Amazon and Microsoft call functions in their cloud definitions. This model of microservices could be called event services because they run to process a single step or event rather than to carry out a multistep transaction.
Many companies, including popular social media platforms, built their web applications on this stateless microservices model because their applications' interactions with users were characterized as event-driven. IoT applications are likely to follow the same path.
Software teams can also spin up a stateless microservice whenever needed, and only when needed. This is the basis of serverless computing: a model of cloud computing designed to commit resources to events only when they actually occur rather than in anticipation of their use. True serverless computing can only use stateless components. Cloud providers try to avoid terminology confusion by calling their serverless offerings functions or lambdas as opposed to microservices.
Merging the models
One important trend in application design serves to merge the transactional and event models. Most enterprises that use public cloud services to support their business applications do so by cloud-hosting the front-end portion of the application. This split enables them to decompose the workflow into a series of events that lend themselves to processing using stateless microservices without affecting the back end of the application design.
This decomposition relies on a state processing mechanism that doesn't require information to be stored in the microservice instance, which, strictly speaking, isn't a stateless model. But back-end state control, front-end state control and other mechanisms for providing a stateless microservice instance with state information are all workable. The best strategy will depend on the application itself.
Another approach to performing stateful or contextual processes while using stateless microservices is one designed to work with serverless computing. This method is based on an orchestration layer, such as AWS Step Functions or Azure Logic Apps. This method puts a series of events into context within an interpretive state structure and transaction translator. It's possible to do the same thing with your own logic by following event development principles, with back-end database technology to synchronize the steps across multiple instances.
The use of the term microservice to describe both stateless and stateful architectures hasn't been helpful to development teams. Many people believe microservice means a small service, and the fact that most services in other architectures were modeled on predominately stateful standards like SOA, a misguided connotation between statefulness and the term microservice arose.
Perhaps the cloud trend of using the terms function or lambda to define a truly stateless microservice, distinct from stateful microservices, is a better approach, but because we can't turn back time on the terminology, it's important to understand what kind of microservices you're using and how to work with them to deliver software requirements.