Microservices

Last updated

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. [1]

Contents

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. [2] [3] [4]

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. [5] 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. [6] With microservices, only the microservice supporting the function with resource constraints needs to be scaled out, thus providing resource and cost optimization benefits. [7]

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. [8]

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. [9] 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. [10]

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. [11] [12]

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. [13] 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. [14]

Benefits

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

Criticism and concerns

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

Complexities

The architecture introduces additional complexity and new problems to deal with, such as latency, message format design, [32] backup/availability/consistency (BAC), [33] load balancing and fault tolerance. [34] 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. [35] 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. [36] 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

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. [11]

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. [37]

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. [11]

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. [38]

The Eclipse Foundation has published a specification for developing microservices, Eclipse MicroProfile. [39] [40]

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

Related Research Articles

Distributed computing is a field of computer science that studies distributed systems, defined as computer systems whose inter-communicating components are located on different networked computers.

In software engineering, multitier architecture is a client–server architecture in which presentation, application processing and data management functions are physically separated. The most widespread use of multitier architecture is the three-tier architecture.

<span class="mw-page-title-main">Software architecture</span> High level structures of a software system

Software architecture is the set of structures needed to reason about a software system and the discipline of creating such structures and systems. Each structure comprises software elements, relations among them, and properties of both elements and relations.

In software engineering, service-oriented architecture (SOA) is an architectural style that focuses on discrete services instead of a monolithic design. SOA is a good choice for system integration. By consequence, it is also applied in the field of software design where services are provided to the other components by application components, through a communication protocol over a network. A service is a discrete unit of functionality that can be accessed remotely and acted upon and updated independently, such as retrieving a credit card statement online. SOA is also intended to be independent of vendors, products and technologies.

REST is a software architectural style that was created to guide the design and development of the architecture for the World Wide Web. REST defines a set of constraints for how the architecture of a distributed, Internet-scale hypermedia system, such as the Web, should behave. The REST architectural style emphasises uniform interfaces, independent deployment of components, the scalability of interactions between them, and creating a layered architecture to promote caching to reduce user-perceived latency, enforce security, and encapsulate legacy systems.

Software multitenancy is a software architecture in which a single instance of software runs on a server and serves multiple tenants. Systems designed in such manner are "shared". A tenant is a group of users who share a common access with specific privileges to the software instance. With a multitenant architecture, a software application is designed to provide every tenant a dedicated share of the instance—including its data, configuration, user management, tenant individual functionality and non-functional properties. Multitenancy contrasts with multi-instance architectures, where separate software instances operate on behalf of different tenants.

<span class="mw-page-title-main">Monolithic application</span> Software design pattern

In software engineering, a monolithic application is a single unified software application that is self-contained and independent from other applications, but typically lacks flexibility. There are advantages and disadvantages of building applications in a monolithic style of software architecture, depending on requirements. Monolith applications are relatively simple and have a low cost but their shortcomings are lack of elasticity, fault tolerance and scalability. Alternative styles to monolithic applications include multitier architectures, distributed computing and microservices. Despite their popularity in recent years, monolithic applications are still a good choice for applications with small team and little complexity. However, once it becomes too complex, you can consider refactoring it into microservices or a distributed application. Note that a monolithic application deployed on a single machine, may be performant enough for your current workload but it's less available, less durable, less changeable, less fine-tuned and less scalable than a well designed distributed system.

Domain-driven design (DDD) is a major software design approach, focusing on modeling software to match a domain according to input from that domain's experts. DDD is against the idea of having a single unified model; instead it divides a large system into bounded contexts, each of which have their own model.

<span class="mw-page-title-main">Cloud computing</span> Form of shared internet-based computing

"Cloud computing is a paradigm for enabling network access to a scalable and elastic pool of shareable physical or virtual resources with self-service provisioning and administration on-demand," according to ISO.

DevOps is a methodology integrating and automating the work of software development (Dev) and information technology operations (Ops). It serves as a means for improving and shortening the systems development life cycle. DevOps is complementary to agile software development; several DevOps aspects came from the agile approach.

An application programming interface (API) is a connection between computers or between computer programs. It is a type of software interface, offering a service to other pieces of software. A document or standard that describes how to build such a connection or interface is called an API specification. A computer system that meets this standard is said to implement or expose an API. The term API may refer either to the specification or to the implementation.

Software-defined networking (SDN) is an approach to network management that uses abstraction to enable dynamic and programmatically efficient network configuration to create grouping and segmentation while improving network performance and monitoring in a manner more akin to cloud computing than to traditional network management. SDN is meant to improve the static architecture of traditional networks and may be employed to centralize network intelligence in one network component by disassociating the forwarding process of network packets from the routing process. The control plane consists of one or more controllers, which are considered the brains of the SDN network, where the whole intelligence is incorporated. However, centralization has certain drawbacks related to security, scalability and elasticity.

Continuous delivery (CD) is a software engineering approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time. It aims at building, testing, and releasing software with greater speed and frequency. The approach helps reduce the cost, time, and risk of delivering changes by allowing for more incremental updates to applications in production. A straightforward and repeatable deployment process is important for continuous delivery.

<span class="mw-page-title-main">Cloud computing architecture</span>

Cloud computing architecture refers to the components and subcomponents required for cloud computing. These components typically consist of a front end platform, back end platforms, a cloud based delivery, and a network. Combined, these components make up cloud computing architecture.

Software intelligence is insight into the inner workings and structural condition of software assets produced by software designed to analyze database structure, software framework and source code to better understand and control complex software systems in information technology environments. Similarly to business intelligence (BI), software intelligence is produced by a set of software tools and techniques for the mining of data and the software's inner-structure. Results are automatically produced and feed a knowledge base containing technical documentation and blueprints of the innerworking of applications, and make it available to all to be used by business and software stakeholders to make informed decisions, measure the efficiency of software development organizations, communicate about the software health, prevent software catastrophes.

<span class="mw-page-title-main">AWS Lambda</span> Serverless computing platform

AWS Lambda is an event-driven, serverless Function as a Service (FaaS) provided by Amazon as a part of Amazon Web Services. It is designed to enable developers to run code without provisioning or managing servers. It executes code in response to events and automatically manages the computing resources required by that code. It was introduced on November 13, 2014.

"Serverless computing is a cloud service category in which the customer can use different cloud capabilities types without the customer having to provision, deploy and manage either hardware or software resources, other than providing customer application code or providing customer data. Serverless computing represents a form of virtualized computing." according to ISO/IEC 22123-2 Function as a service and serverless database are two forms of serverless computing.

Function as a service (FaaS) is a category of cloud computing services that provides a platform allowing customers to develop, run, and manage application functionalities without the complexity of building and maintaining the infrastructure typically associated with developing and launching an app. Building an application following this model is one way of achieving a "serverless" architecture, and is typically used when building microservices applications.

A Micro-app is a super-specialized application designed to perform one task or use case with the only objective of doing it well. They follow the single responsibility principle, which states that "a class should have one and only one reason to change." Micro applications help developers create less complex applications while reducing costs by breaking down monolithic systems into groups of independent services acting as one system. A good example of Microapps would be https://docs.citrix.com/en-us/legacy-archive/downloads/microapps.pdfthat provide single purpose action from Salesforce and over 40 applications on its workspace.

Cell-based Architecture (CBA) is a software design paradigm that structures applications as a collection of small, self-contained units called "cells." Each cell encapsulates specific functionality along with its own data, logic, and state, enabling independent development, deployment, and scaling. CBA is a holistic approach that combines aspects of application architecture, deployment architecture, and organizational (people/team) architecture. This integration aligns technical design with team structures, promoting modularity, agility, and efficient collaboration across development processes.

References

  1. Fowler, Martin (2002). Patterns of Enterprise Application Architecture. Addison-Wesley Professional. ISBN   978-0321127426.
  2. Newman, Sam (2015-02-20). Building Microservices. O'Reilly Media. ISBN   978-1491950357.
  3. Wolff, Eberhard (2016-10-12). Microservices: Flexible Software Architectures. Addison-Wesley. ISBN   978-0134602417.
  4. Nadareishvili, I., Mitra, R., McLarty, M., Amundsen, M., Microservice Architecture: Aligning Principles, Practices, and Culture, O'Reilly 2016
  5. Martin Fowler (28 August 2014). "Microservice Prerequisites". Archived from the original on Oct 3, 2023.
  6. Richardson, Chris (November 2018). Microservice Patterns. Manning Publications. 1.4.1 Scale cube and microservices. ISBN   9781617294549.
  7. Mendonca, Nabor C.; Jamshidi, Pooyan; Garlan, David; Pahl, Claus (2019-10-16). "Developing Self-Adaptive Microservice Systems: Challenges and Directions". IEEE Software. 38 (2): 70–79. arXiv: 1910.07660 . doi:10.1109/MS.2019.2955937. S2CID   204744007.
  8. Research, Verified Market. "Cloud Microservices Market 2020 Trends, Market Share, Industry Size, Opportunities, Analysis and Forecast by 2026 – Instant Tech Market News" . Retrieved 2020-02-18.
  9. Russell, Perry; Rodgers, Peter; Sellman, Royston (2004). "Architecture and Design of an XML Application Platform". HP Technical Reports. p. 62. Retrieved 20 August 2015.
  10. Rodgers, Peter (Feb 15, 2005). "Service-Oriented Development on NetKernel- Patterns, Processes & Products to Reduce System Complexity". CloudComputingExpo. SYS-CON Media. Archived from the original on 20 May 2018. Retrieved 19 August 2015.
  11. 1 2 3 Fundamentals of Software Architecture: An Engineering Approach. O'Reilly Media. 2020. ISBN   978-1492043454.
  12. Building Evolutionary Architectures: Support Constant Change. O'Reilly Media. ISBN   978-1491986363.
  13. Fundamentals of Software Architecture: An Engineering Approach. O'Reilly Media. 2020. ISBN   978-1492043454.
  14. Building Microservices by Sam Newman. ISBN   978-1492034025.
  15. 1 2 Chen, Lianping (2018). Microservices: Architecting for Continuous Delivery and DevOps. The IEEE International Conference on Software Architecture (ICSA 2018). IEEE.
  16. Yousif, Mazin (2016). "Microservices". IEEE Cloud Computing. 3 (5): 4–5. doi:10.1109/MCC.2016.101.
  17. Dragoni, Nicola; Lanese, Ivan; Larsen, Stephan Thordal; Mazzara, Manuel; Mustafin, Ruslan; Safina, Larisa (2017). "Microservices: How to Make Your Application Scale" (PDF). Perspectives of System Informatics. Lecture Notes in Computer Science. Vol. 10742. pp. 95–104. arXiv: 1702.07149 . Bibcode:2017arXiv170207149D. doi:10.1007/978-3-319-74313-4_8. ISBN   978-3-319-74312-7. S2CID   1643730.
  18. Newman, Sam (2015). Building Microservices. O'Reilly. ISBN   978-1491950357.
  19. Wolff, Eberhard (2016). Microservices: Flexible Software Architecture. Addison Wesley. ISBN   978-0134602417.
  20. Knoche, Holger; Hasselbring, Wilhelm (2019). "Drivers and Barriers for Microservice Adoption – A Survey among Professionals in Germany". Enterprise Modelling and Information Systems Architectures. 14: 1:1–35–1:1–35. doi:10.18417/emisa.14.1.
  21. 1 2 Taibi, Davide; Lenarduzzi, Valentina; Pahl, Claus; Janes, Andrea (2017). "Microservices in agile software development: a workshop-based study into issues, advantages, and disadvantages". Proceedings of the XP2017 Scientific Workshops. doi:10.1145/3120459.3120483. S2CID   28134110.
  22. Richardson, Chris. "Microservice architecture pattern". microservices.io. Retrieved 2017-03-19.
  23. Chen, Lianping; Ali Babar, Muhammad (2014). "Towards an Evidence-Based Understanding of Emergence of Architecture through Continuous Refactoring in Agile Software Development". Proceedings Working IEEE/IFIP Conference on Software Architecture 2014 WICSA 2014. The 11th Working IEEE/IFIP Conference on Software Architecture(WICSA 2014). IEEE. doi:10.1109/WICSA.2014.45.
  24. Balalaie, Armin; Heydarnoori, Abbas; Jamshidi, Pooyan (May 2016). "Microservices Architecture Enables DevOps: Migration to a Cloud-Native Architecture" (PDF). IEEE Software. 33 (3): 42–52. doi:10.1109/ms.2016.64. hdl:10044/1/40557. ISSN   0740-7459. S2CID   18802650.
  25. Stenberg, Jan (11 August 2014). "Experiences from Failing with Microservices".
  26. 1 2 Martin Fowler. "Microservices". Archived from the original on 14 February 2018.
  27. Calandra, Mariano (7 April 2021). "Why unit testing is not enough when it comes to microservices".
  28. Lanza, Michele; Ducasse, Stéphane (2002). "Understanding Software Evolution using a Combination of Software Visualization and Software Metrics" (PDF). In Proceedings of LMO 2002 (Langages et Modèles à Objets): 135–149. Archived from the original (PDF) on Feb 27, 2021.
  29. Richardson, Chris (November 2018). "Chapter 4. Managing transactions with sagas". Microservice Patterns. Manning Publications. ISBN   978-1-61729454-9.
  30. Devoxx (Aug 30, 2017). "10 Tips for failing badly at Microservices by David Schmitz". YouTube . Archived from the original on Apr 22, 2021.
  31. 1 2 3 Löwy, Juval (2019). Righting Software 1st ed. Addison-Wesley Professional. pp. 73–75. ISBN   978-0136524038.
  32. Pautasso, Cesare (2017). "Microservices in Practice, Part 2: Service Integration and Sustainability". IEEE Software. 34 (2): 97–104. doi:10.1109/MS.2017.56. S2CID   30256045.
  33. Pautasso, Cesare (2018). "Consistent Disaster Recovery for Microservices: the BAC Theorem". IEEE Cloud Computing. 5 (1): 49–59. doi:10.1109/MCC.2018.011791714. S2CID   4560021.
  34. "Developing Microservices for PaaS with Spring and Cloud Foundry".
  35. Fowler, Martin. "Microservice Trade-Offs".
  36. "BRASS Building Resource Adaptive Software Systems". U.S. Government. DARPA. 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".
  37. 1 2 3 Richards, Mark. Microservices AntiPatterns and Pitfalls. O'Reilly.
  38. Wolff, Eberhard (2018-04-15). Microservices - A Practical Guide. CreateSpace Independent Publishing Platform. ISBN   978-1717075901.
  39. Swart, Stephanie (14 December 2016). "Eclipse MicroProfile". projects.eclipse.org.
  40. "MicroProfile". MicroProfile. Retrieved 2021-04-11.

Further reading