Microservices

{{short description|Collection of loosely coupled services used to build computer applications}}

In software engineering, a microservice architecture is an architectural pattern that organizes an application into a collection of loosely coupled, fine-grained services that communicate through lightweight protocols. This pattern is characterized by the ability to develop and deploy services independently, improving modularity, scalability, and adaptability. However, it introduces additional complexity, particularly in managing distributed systems and inter-service communication, making the initial implementation more challenging compared to a monolithic architecture. {{Cite book |last=Fowler |first=Martin |title=Patterns of Enterprise Application Architecture |publisher=Addison-Wesley Professional |year=2002 |isbn=978-0321127426}}

Definition

There is no single, universally agreed-upon definition of microservices. However, they are generally characterized by a focus on modularity, with each service designed around a specific business capability. These services are loosely coupled, independently deployable, and often developed and scaled separately, enabling greater flexibility and agility in managing complex systems. Microservices architecture is closely associated with principles such as domain-driven design, decentralization of data and governance, and the flexibility to use different technologies for individual services to best meet their requirements. {{cite book |last=Newman |first=Sam |title=Building Microservices |date=2015-02-20 |publisher=O'Reilly Media |isbn=978-1491950357}}{{cite book |last1=Wolff |first1=Eberhard |title=Microservices: Flexible Software Architectures |date=2016-10-12 |publisher=Addison-Wesley |isbn=978-0134602417}}Nadareishvili, I., Mitra, R., McLarty, M., Amundsen, M., Microservice Architecture: Aligning Principles, Practices, and Culture, O'Reilly 2016

Usage

It is common for microservices architectures to be adopted for cloud-native applications, serverless computing, and applications using lightweight container deployment. According to Fowler, because of the large number (when compared to monolithic application implementations) of services, decentralized continuous delivery and DevOps with holistic service monitoring are necessary to effectively develop, maintain, and operate such applications.{{cite web|url=https://martinfowler.com/bliki/MicroservicePrerequisites.html|title=Microservice Prerequisites|author=Martin Fowler|author-link=Martin Fowler (software engineer) |date=28 August 2014 |url-status=live |archive-url=https://web.archive.org/web/20231003075551/https://martinfowler.com/bliki/MicroservicePrerequisites.html |archive-date=Oct 3, 2023 }} A consequence of (and rationale for) following this approach is that the individual microservices can be individually scaled. In the monolithic approach, an application supporting three functions would have to be scaled in its entirety even if only one of these functions had a resource constraint.{{cite book |last1=Richardson |first1=Chris |title=Microservice Patterns |date=November 2018 |publisher=Manning Publications |at=1.4.1 Scale cube and microservices |isbn=9781617294549}} With microservices, only the microservice supporting the function with resource constraints needs to be scaled out, thus providing resource and cost optimization benefits.{{cite journal|last1=Mendonca|first1=Nabor C.|last2=Jamshidi|first2=Pooyan|last3=Garlan|first3=David|last4=Pahl|first4=Claus|date=2019-10-16|title=Developing Self-Adaptive Microservice Systems: Challenges and Directions|journal=IEEE Software|volume=38|issue=2|pages=70–79|doi=10.1109/MS.2019.2955937|arxiv=1910.07660|s2cid=204744007 }}

In February 2020, the Cloud Microservices Market Research Report predicted that the global microservice architecture market size will increase at a CAGR of 21.37% from 2019 to 2026 and reach $3.1 billion by 2026.{{Cite web|url=https://www.instanttechnews.com/technology-news/2020/02/16/cloud-microservices-market-2020-trends-market-share-industry-size-opportunities-analysis-and-forecast-by-2026/|title=Cloud Microservices Market 2020 Trends, Market Share, Industry Size, Opportunities, Analysis and Forecast by 2026 – Instant Tech Market News|last=Research|first=Verified Market|language=en-US|access-date=2020-02-18}}

Cell-based architecture in microservices

Cell-based architecture is a distributed computing design in which computational resources are organized into self-contained units called cells. Each cell operates independently, handling a subset of requests while maintaining scalability, fault isolation, and availability. {{Cite book |last=Richardson |first=Chris |title=Microservices patterns: with examples in Java |date=2019 |publisher=Manning Publications |isbn=978-1-61729-454-9 |location=Shelter Island, NY}}{{Cite book |last=Christudas |first=Binildas |title=Practical Microservices Architectural Patterns: Event-Based Java Microservices with Spring Boot and Spring Cloud |date=2019 |publisher=Apress L. P |isbn=978-1-4842-4501-9 |location=Berkeley, CA}}

A cell typically consists of multiple microservices and functions as an autonomous unit. In some implementations, entire sets of microservices are replicated across multiple cells, enabling requests to be rerouted to another operational cell if one experiences a failure. This approach is intended to improve system-wide resilience by limiting the impact of localized failures.

Some implementations incorporate circuit breakers within and between cells. Within a cell, circuit breakers may be used to mitigate cascading failures among microservices, while inter-cell circuit breakers can isolate failing cells and redirect traffic to those that remain operational.

Cell-based architecture has been adopted in certain large-scale distributed systems where fault isolation and redundancy are design priorities. Its implementation varies based on system requirements, infrastructure constraints, and specific operational goals.

History

In 1999, software developer Peter Rodgers had been working on the Dexter research project at Hewlett Packard Labs, whose aim was to make code less brittle and to make large-scale, complex software systems robust to change.{{cite web|last1= Russell|first1= Perry|last2=Rodgers|first2= Peter|last3= Sellman|first3= Royston|title= Architecture and Design of an XML Application Platform|url= http://www.hpl.hp.com/techreports/2004/HPL-2004-23.html|website= HP Technical Reports|access-date= 20 August 2015|pages= 62|date= 2004}} Ultimately this path of research led to the development of resource-oriented computing (ROC), a generalized computation abstraction in which REST is a special subset. In 2005, during a presentation at the Web Services Edge conference, Rodgers argued for "REST-services" and stated that "Software components are Micro-Web-Services... Micro-Services are composed using Unix-like pipelines (the Web meets Unix = true loose-coupling). Services can call services (+multiple language run-times). Complex service assemblies are abstracted behind simple URI interfaces. Any service, at any granularity, can be exposed." He described how a well-designed microservices platform "applies the underlying architectural principles of the Web and REST services together with Unix-like scheduling and pipelines to provide radical flexibility and improved simplicity in service-oriented architectures.{{cite web|last1= Rodgers|first1= Peter|title= Service-Oriented Development on NetKernel- Patterns, Processes & Products to Reduce System Complexity|url= http://www.cloudcomputingexpo.com/node/80883|website= CloudComputingExpo|publisher= SYS-CON Media |date=Feb 15, 2005 |access-date= 19 August 2015|archive-url= https://web.archive.org/web/20180520124343/http://www.cloudcomputingexpo.com/node/80883|archive-date= 20 May 2018|url-status= dead}}

Also in 2005, Alistair Cockburn wrote about hexagonal architecture which is a software design pattern that is used along with the microservices. This pattern makes the design of the microservice possible since it isolates in layers the business logic from the auxiliary services needed in order to deploy and run the microservice completely independent from others.

Microservice granularity

Determining the appropriate level of (micro)service granularity in a microservices architecture often requires iterative collaboration between architects and developers. This process involves evaluating user requirements, service responsibilities, and architectural characteristics, such as non-functional requirements. Neal Ford highlights the role of integrator and disintegrator factors in this context. Integrator factors, such as shared transactions or tightly coupled processes, favor combining services, while disintegrator factors, such as fault tolerance or independent scalability, encourage splitting services to meet operational and architectural goals. Additionally, fitness functions, as proposed by Neal Ford, can be used to validate architectural decisions and service granularity by continuously measuring system qualities or behaviors that are critical to stakeholders, ensuring alignment with overall architectural objectives. {{Cite book |title=Fundamentals of Software Architecture: An Engineering Approach |publisher=O'Reilly Media |year=2020 |isbn=978-1492043454}}{{Cite book |title=Building Evolutionary Architectures: Support Constant Change |date=2017 |publisher=O'Reilly Media |isbn=978-1491986363}}

Mapping microservices to bounded contexts

A bounded context, a fundamental concept in domain-driven design (DDD), defines a specific area within which a domain model is consistent and valid, ensuring clarity and separation of concerns. {{Cite book |title=Fundamentals of Software Architecture: An Engineering Approach |publisher=O'Reilly Media |year=2020 |isbn=978-1492043454}} In microservices architecture, a bounded context often maps to a microservice, but this relationship can vary depending on the design approach. A one-to-one relationship, where each bounded context is implemented as a single microservice, is typically ideal as it maintains clear boundaries, reduces coupling, and enables independent deployment and scaling. However, other mappings may also be appropriate: a one-to-many relationship can arise when a bounded context is divided into multiple microservices to address varying scalability or other operational needs, while a many-to-one relationship may consolidate multiple bounded contexts into a single microservice for simplicity or to minimize operational overhead. The choice of relationship should balance the principles of DDD with the system's business goals, technical constraints, and operational requirements. {{Cite book |title=Building Microservices by Sam Newman |isbn=978-1492034025}}

Benefits

The benefit of decomposing an application into different smaller services are numerous:

  • Modularity: This makes the application easier to understand, develop, test, and become more resilient to architecture erosion.{{cite conference

|url= https://www.researchgate.net/publication/323944215

|title= Microservices: Architecting for Continuous Delivery and DevOps

|first= Lianping |last= Chen

|date= 2018

|conference= The IEEE International Conference on Software Architecture (ICSA 2018)

|conference-url= http://icsa-conferences.org/2018/

|publisher= IEEE}} This benefit is often argued in comparison to the complexity of monolithic architectures.{{Cite journal|last=Yousif|first=Mazin|date=2016|

title=Microservices

|journal=IEEE Cloud Computing

|volume=3|issue=5|pages=4–5|doi=10.1109/MCC.2016.101}}

  • Scalability: Since microservices are implemented and deployed independently of each other, i.e. they run within independent processes, they can be monitored and scaled independently.

{{Cite book|last1=Dragoni|first1=Nicola|last2=Lanese|first2=Ivan|last3=Larsen|first3=Stephan Thordal|last4=Mazzara|first4=Manuel|last5=Mustafin|first5=Ruslan|last6=Safina|first6=Larisa|title=Perspectives of System Informatics |chapter=Microservices: How to Make Your Application Scale |date=2017|series=Lecture Notes in Computer Science|volume=10742|chapter-url=https://hal.inria.fr/hal-01636132/file/microservices-make-application.pdf

|pages=95–104|doi=10.1007/978-3-319-74313-4_8|bibcode=2017arXiv170207149D|arxiv=1702.07149|isbn=978-3-319-74312-7|s2cid=1643730}}

  • Integration of heterogeneous and legacy systems: microservices are considered a viable means for modernizing existing monolithic software application.

{{cite book |last=Newman |first=Sam |date=2015 |title=Building Microservices |publisher=O'Reilly|isbn= 978-1491950357}}

{{cite book |last=Wolff |first=Eberhard |date=2016 |title=Microservices: Flexible Software Architecture |publisher=Addison Wesley|isbn= 978-0134602417}}

There are experience reports of several companies who have successfully replaced parts of their existing software with microservices or are in the process of doing so.

{{Cite journal|last1=Knoche|first1=Holger|last2=Hasselbring|first2=Wilhelm

|date=2019

|title=Drivers and Barriers for Microservice Adoption – A Survey among Professionals in Germany

|journal=Enterprise Modelling and Information Systems Architectures

|volume=14|pages=1:1–35–1:1–35|url=https://www.researchgate.net/publication/330442182

|doi = 10.18417/emisa.14.1}}

The process for software modernization of legacy applications is done using an incremental approach.{{Cite book|last1=Taibi|first1=Davide|last2=Lenarduzzi|first2=Valentina|last3=Pahl|first3=Claus|last4=Janes|first4=Andrea |title=Proceedings of the XP2017 Scientific Workshops |chapter=Microservices in agile software development: A workshop-based study into issues, advantages, and disadvantages |date=2017|pages=1–5 |chapter-url=https://www.researchgate.net/publication/319131505|doi=10.1145/3120459.3120483|isbn=978-1-4503-5264-2 |s2cid=28134110}}

  • Distributed development: it parallelizes development by enabling small autonomous teams to develop, deploy and scale their respective services independently.{{Cite web|url=http://microservices.io/patterns/microservices.html|title=Microservice architecture pattern|last=Richardson|first=Chris|website=microservices.io|access-date=2017-03-19}} It also allows the architecture of an individual service to emerge through continuous refactoring.{{cite conference

|title= Towards an Evidence-Based Understanding of Emergence of Architecture through Continuous Refactoring in Agile Software Development

|first1= Lianping |last1= Chen

|first2= Muhammad|last2= Ali Babar|date= 2014

|book-title=Proceedings Working IEEE/IFIP Conference on Software Architecture 2014 WICSA 2014

|conference= The 11th Working IEEE/IFIP Conference on Software Architecture(WICSA 2014)

|conference-url=https://web.archive.org/web/20140730053454/http://wicsa2014.org/

|publisher= IEEE

|doi = 10.1109/WICSA.2014.45}}

Microservice-based architectures facilitate continuous integration, continuous delivery and deployment.{{Cite journal|last1=Balalaie|first1=Armin|last2=Heydarnoori|first2=Abbas|last3=Jamshidi|first3=Pooyan|date=May 2016|title=Microservices Architecture Enables DevOps: Migration to a Cloud-Native Architecture|journal=IEEE Software|volume=33|issue=3|pages=42–52|doi=10.1109/ms.2016.64|issn=0740-7459|hdl=10044/1/40557|s2cid=18802650|url=http://spiral.imperial.ac.uk/bitstream/10044/1/40557/8/SO_SWSI-2015-10-0149.R1_Balalaie.pdf}}

Criticism and concerns

The microservices approach is subject to criticism for a number of issues:

  • Services form information barriers.{{cite web|url= http://www.infoq.com/news/2014/08/failing-microservices|title=Experiences from Failing with Microservices| first =Jan | last = Stenberg|date=11 August 2014}}
  • Inter-service calls over a network have a higher cost in terms of network latency and message processing time than in-process calls within a monolithic service process.{{cite web |author=Martin Fowler |title=Microservices |url=http://martinfowler.com/articles/microservices.html |url-status=live |archive-url=https://web.archive.org/web/20180214171522/https://martinfowler.com/articles/microservices.html |archive-date=14 February 2018}}
  • Testing and deployment can be complicated.{{cite web|url=https://medium.com/swlh/why-unit-testing-is-not-enough-when-it-comes-to-microservices-c3b0dde14174|last=Calandra|first=Mariano|title=Why unit testing is not enough when it comes to microservices|date=7 April 2021}}
  • Moving responsibilities between services is more difficult. It may involve communication between different teams, rewriting the functionality in another language or fitting it into a different infrastructure. However, microservices can be deployed independently from the rest of the application, while teams working on monoliths need to synchronize to deploy together.
  • Viewing the size of services as the primary structuring mechanism can lead to too many services when the alternative of internal modularization may lead to a simpler design. This requires understanding the overall architecture of the applications and interdependencies between components.{{cite journal |last1=Lanza |first1=Michele |last2=Ducasse |first2=Stéphane|date=2002 |title= Understanding Software Evolution using a Combination of Software Visualization and Software Metrics|url=https://rmod.inria.fr/archives/papers/Lanz02aEvolutionMatrix.pdf |journal=Proceedings of LMO 2002 (Langages et Modèles à Objets)|pages=135–149 |url-status=dead |archive-url=https://web.archive.org/web/20210227104157/https://rmod.inria.fr/archives/papers/Lanz02aEvolutionMatrix.pdf |archive-date= Feb 27, 2021 }}
  • Two-phased commits are regarded as an anti-pattern in microservices-based architectures, resulting in a tighter coupling of all the participants within the transaction. However, the lack of this technology causes awkward dances which have to be implemented by all the transaction participants in order to maintain data consistency.{{cite book |last1= Richardson |first1= Chris |title= Microservice Patterns |date= November 2018 |publisher= Manning Publications |chapter=Chapter 4. Managing transactions with sagas|isbn= 978-1-61729454-9}}
  • Development and support of many services are more challenging if they are built with different tools and technologies - this is especially a problem if engineers move between projects frequently.{{Cite web|url=https://www.youtube.com/watch?v=X0tjziAQfNQ|title = 10 Tips for failing badly at Microservices by David Schmitz |last1=Devoxx |date=Aug 30, 2017 |website = YouTube |url-status=dead |archive-url=https://web.archive.org/web/20210422161909/https://www.youtube.com/watch?v=X0tjziAQfNQ |archive-date= Apr 22, 2021 }}
  • The protocol typically used with microservices (HTTP) was designed for public-facing services, and as such is unsuitable for working internal microservices that often must be impeccably reliable.{{Cite book|title=Righting Software 1st ed.|last=Löwy|first=Juval|publisher=Addison-Wesley Professional|year=2019|isbn=978-0136524038|pages=73–75}}
  • While not specific to microservices, the decomposition methodology often uses functional decomposition, which does not handle changes in the requirements while still adding the complexity of services.
  • The very concept of microservice is misleading since there are only services. There is no sound definition of when a service starts or stops being a microservice.
  • Data aggregation. In order to have a full view of a working system, it is required to extract data sets from the microservices repositories and aggregate them into a single schema. For example, to be able to create operational reports that are not possible using a single microservice repository.

= Complexities =

The architecture introduces additional complexity and new problems to deal with, such as latency, message format design,{{Cite journal|year= 2017|title= Microservices in Practice, Part 2: Service Integration and Sustainability |journal= IEEE Software |volume=34|issue=2|pages= 97–104|doi=10.1109/MS.2017.56 |last1=Pautasso|first1= Cesare|s2cid= 30256045 }} backup/availability/consistency (BAC),{{Cite journal|year=2018|title=Consistent Disaster Recovery for Microservices: the BAC Theorem|journal=IEEE Cloud Computing|volume=5|issue=1|pages=49–59|doi=10.1109/MCC.2018.011791714|last1=Pautasso|first1=Cesare|s2cid=4560021}} load balancing and fault tolerance.{{cite web|url= http://www.infoq.com/presentations/microservices-pass-spring-cloud-foundry|title=Developing Microservices for PaaS with Spring and Cloud Foundry}} All of these problems have to be addressed at scale. The complexity of a monolithic application does not disappear if it is re-implemented as a set of microservices. Some of the complexity gets translated into operational complexity.{{cite web|author-link = Martin Fowler (software engineer)| first = Martin | last = Fowler |url= https://www.martinfowler.com/articles/microservice-trade-offs.html#ops |title=Microservice Trade-Offs}} Other places where the complexity manifests itself are increased network traffic and resulting in slower performance. Also, an application made up of any number of microservices has a larger number of interface points to access its respective ecosystem, which increases the architectural complexity.{{cite news|title= BRASS Building Resource Adaptive Software Systems |agency= DARPA |publisher=U.S. Government |date= April 7, 2015}} "Access to system components and the interfaces between clients and their applications, however, are mediated via a number of often unrelated mechanisms, including informally documented application programming interfaces (APIs), idiosyncratic foreign function interfaces, complex ill-understood model definitions, or ad hoc data formats. These mechanisms usually provide only partial and incomplete understanding of the semantics of the components themselves. In the presence of such complexity, it is not surprising that applications typically bake-in many assumptions about the expected behavior of the ecosystem they interact with". Various organizing principles (such as hypermedia as the engine of application state (HATEOAS), interface and data model documentation captured via Swagger, etc.) have been applied to reduce the impact of such additional complexity.

Antipatterns

{{single source|section|date=April 2025}}

  • The "data-driven migration antipattern", coined by Mark Richards, highlights the challenges of prioritizing data migration during the transition from a monolithic to a microservices architecture. To address this antipattern, an iterative approach can be helpful where application code is migrated first, with new microservices temporarily relying on the existing monolithic database. Over time, as the system is better understood, data can be decoupled and restructured, enabling individual microservices to operate with their own databases. This strategy can simplify the migration process and reduce data migration errors.{{Cite book |last=Richards |first=Mark |title=Microservices AntiPatterns and Pitfalls |publisher=O'Reilly}}
  • The "timeout antipattern", coined by Mark Richards, describes the challenges of setting timeout values in distributed systems. Short timeouts may fail legitimate requests prematurely, leading to complex workarounds, while long timeouts can result in slow error responses and poor user experiences. The circuit breaker pattern can address these issues by monitoring service health through mechanisms such as heartbeats, "synthetic transactions", or real-time usage monitoring. This approach can enable faster failure detection and can improve the overall user experience in distributed architectures.
  • Reporting on microservices data presents challenges, as retrieving data for a reporting service can either break the bounded contexts of microservices, reduce the timeliness of the data, or both. This applies regardless of whether data is pulled directly from databases, retrieved via HTTP, or collected in batches. Mark Richards refers to this as the "reach-in reporting antipattern". A possible alternative to this approach is for databases to asynchronously push the necessary data to the reporting service instead of the reporting service pulling it. While this method requires a separate contract between microservices and the reporting service and can be complex to implement, it helps preserve bounded contexts while maintaining a high level of data timeliness.

Challenges

Microservices are susceptible to the fallacies of distributed computing, a series of misconceptions that can lead to significant issues in software development and deployment.

= Code sharing challenges =

Ideally, microservices follow a "share-nothing" architecture. However, in practice, microservices architectures often encounter situations where code must be shared across services. Common approaches to addressing this challenge include utilizing separate shared libraries for reusable components (e.g., a security library), replicating stable modules with minimal changes across services, or, in certain cases, consolidating multiple microservices into a single service to reduce complexity. Each approach has its advantages and trade-offs, depending on the specific context and requirements.

Best practices

According to O'Reilly, each microservice should have its own architectural characteristics (a.k.a. non functional requirements), and architects should not define uniform characteristics for the entire distributed system.

Technologies

Computer microservices can be implemented in different programming languages and might use different infrastructures. Therefore, the most important technology choices are the way microservices communicate with each other (synchronous, asynchronous, UI integration) and the protocols used for the communication (RESTful HTTP, messaging, GraphQL ...). In a traditional system, most technology choices like the programming language impact the whole system. Therefore, the approach to choosing technologies is quite different.{{cite book|url=http://practical-microservices.com|title=Microservices - A Practical Guide|isbn=978-1717075901|last1=Wolff|first1=Eberhard|date=2018-04-15|publisher=CreateSpace Independent Publishing Platform }}

The Eclipse Foundation has published a specification for developing microservices, Eclipse MicroProfile.{{cite web|url=https://projects.eclipse.org/projects/technology.microprofile|title=Eclipse MicroProfile|first=Stephanie|last=Swart|date=14 December 2016|website=projects.eclipse.org}}{{Cite web|title=MicroProfile|url=https://microprofile.io/|access-date=2021-04-11|website=MicroProfile|language=en-US}}

= Service mesh =

{{See also|Service mesh}}

In a service mesh, each service instance is paired with an instance of a reverse proxy server, called a service proxy, sidecar proxy, or sidecar. The service instance and sidecar proxy share a container, and the containers are managed by a container orchestration tool such as Kubernetes, Nomad, Docker Swarm, or DC/OS. The service proxies are responsible for communication with other service instances and can support capabilities such as service (instance) discovery, load balancing, authentication and authorization, secure communications, and others.

See also

References

{{reflist|30em}}

Further reading

  • {{Cite journal

|title=Special theme issue on microservices

|journal=IEEE Software

|volume=35 |issue=3

|date=May–June 2018

|url=https://ieeexplore.ieee.org/xpl/tocresult.jsp?isnumber=8354413

}}

  • I. Nadareishvili et al., [https://www.ca.com/content/dam/ca/us/files/ebook/microservice-architecture-aligning-principles-practices-and-culture.pdf Microservices Architecture – Aligning Principles, Practices and Culture], O'Reilly, 2016, {{isbn|978-1-491-95979-4}}
  • S. Newman, Building Microservices – Designing Fine-Grained Systems, O'Reilly, 2015 {{isbn|978-1491950357}}
  • Wijesuriya, Viraj Brian (2016-08-29) [https://www.slideshare.net/tyrantbrian/microservice-architecture-65505794 Microservice Architecture, Lecture Notes] - University of Colombo School of Computing, Sri Lanka
  • Christudas Binildas (June 27, 2019). Practical Microservices Architectural Patterns: Event-Based Java Microservices with Spring Boot and Spring Cloud. Apress. {{ISBN|978-1484245002}}.

{{Web interfaces}}

Category:Architectural pattern (computer science)

Category:Service-oriented (business computing)