SOA vs Microservices: Perspectives in Architecture
by Eric O'Rear
Microservice architectures dominate the headlines in today’s software media, typically in deciding whether or not the move to microservices is the right strategy for an engineering team. And even if people aren’t discussing microservices outright, they are talking about technologies –– think Kubernetes, Docker, Envoy, and gRPC –– that largely cater to the needs and pain points of leveraging and managing highly-distributed microservice environments.
While microservices are front and center today, they evolved from an earlier architecture paradigm: service-oriented architectures, or SOAs. SOAs had their primetime in the early 2010s, arguably ‘paving the way’ for microservices. What’s the connection?
These architectures share two principal features:
- Distributed, service-based design
- Organizing software around business concerns instead of IT concerns
These high-level similarities beg the question: If SOA and microservice architectures are trying to deal with similar design challenges, how and why do they differ? What can we learn from the success and failure of these differences?
Service-Oriented Architecture (SOA) is an architectural style that supports service-orientation.
Service-orientation is a way of thinking in terms of services and service-based development and the outcomes of services.
- Is a logical representation of a repeatable business activity that has a specified outcome (e.g., check customer credit, provide weather data, consolidate drilling reports)
- Is self-contained
- May be composed of other services
- Is a “black box” to consumers of the service
The ultimate goal of this philosophy is to increase application value and development velocity by creating an application with modular parts that reflect business domains.
In practice, this means creating services with well-defined boundaries and interfaces, enabling the coherent combination of loosely-coupled services into larger business processes –– the application. These services may or may not be web services, and the languages they are written in can vary.
A generalized SOA has four main parts:
- A consumer layer. This can include end users, third-party APIs, or other external services
- A provider layer. This includes the other services defined in the SOA application
- Enterprise service bus (ESB). ESBs translate messages to the correct message type and coordinate all message traffic between the consumer and provider layers
- Data store. Services within an SOA tend to share as much as possible
A simplified service-oriented architecture for a ride-sharing app. The Enterprise Service Bus (ESB) coordinates communication between consumer and provider layers.
The ESB is the layer of abstraction that handles interservice communication, making sure messages are correctly formatted, and assuming the roles of proxy, gateway, and other infrastructure concerns like orchestration.
This design means ESBs themselves need to be made highly tolerant and available, as performance failures in almost any service can weaken a point (the ESB) that all other services depend on. While there are solutions available, this single point of failure is widely considered a drawback of SOA.
The ESB acts as a point of communication management.
What are microservices? Microservice architectures aim to create single applications out of the interoperation of dozens or hundreds or thousands of relatively light, context-bound services with language-agnostic APIs.
It is critical for deployment velocity that services in a microservice architecture can be written, maintained, and deployed independently, relying on automated management as much as possible. This velocity comes at the cost of complexity as so many independent services network, and can make issue resolution slow, frustrating, and expensive.
The microservice paradigm shines in applications that require fast product iterations, and selective and flexible scaling.
Microservice architectures facilitate selective and dynamic scaling.
Unlike SOA, microservices don’t rely on a shared abstraction layer like an ESB for communication. Instead, lightweight, language-agnostic protocols like HTTP and gRPC are preferred.
Due to microservices’ intense decoupling, management and networking tasks such as load-balancing, automated scaling, container orchestration, and other infrastructure concerns are managed by separate services. It is worth noting that microservice implementations that lack a service mesh layer or standard client libraries can create an unwieldy environment that creates poor developer and user experiences.
The two architecture patterns emphasize decoupling and coordination of independent services, but microservice systems maintain a higher degree of independence, as they don’t rely on a central mechanism like an ESB.
Microservices push independence a step further by maintaining separate data stores for each or most of the services. SOAs, on the other hand, rely on a “share-what-you-can” policy for datastores. This can provide improvements in data performance, but increases coupling.
While both design patterns are distributed, the services, and associated business processes, are usually much larger in scope in SOAs.
Microservice architectures often have an API layer or “gateway”. This is not a middleware layer akin to the ESB. Instead, it is a facade that allows the services to be decoupled from the service consumers. If endpoints need to change, this can be done without requiring changes to the consumer layer.
SOAs and microservices are both service-based architectures, and have a lot in common, sometimes leading to microservices being referred to as SOA 2.0. But, with a clearer emphasis on finger-grained modularity and stricter decoupling, microservice implementations have certainly distinguished themselves: smaller, more focused teams that require minimal coordination across the organization to roll out new features and iterations. Combined with improvements in automated infrastructure and deployment, microservices offer companies of scale an opportunity to develop faster, minimize maintenance overhead, and release more robust and tolerant software.
For a deeper understanding of performance analysis in distributed systems, check out Performance is a Shape, Not a Number.