Microservices

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search

Microservices are a software development technique—a variant of the service-oriented architecture (SOA) architectural style that structures an application as a collection of loosely coupled services. In a microservices architecture, services are fine-grained and the protocols are lightweight. The benefit of decomposing an application into different smaller services is that it improves modularity. This makes the application easier to understand, develop, test, and become more resilient to architecture erosion.[1] It parallelizes development by enabling small autonomous teams to develop, deploy and scale their respective services independently.[2] It also allows the architecture of an individual service to emerge through continuous refactoring.[3] Microservice-based architectures enable continuous delivery and deployment.[4]

Introduction[edit]

Even though there is no official definition of what microservices are, a consensus view has evolved over time, in the industry. Some of the defining characteristics that are frequently cited include:

  • Per Martin Fowler and other experts, services in a microservice architecture (MSA) are often processes that communicate over a network to fulfill a goal using technology-agnostic protocols such as HTTP.[5][6][7]
  • Services in a microservice architecture are independently deployable.[8][1]
  • Services are organized around fine-grained business capabilities. The granularity of the microservice is important - because this is key to how this approach is different from SOA.
  • Services can be implemented using different programming languages, databases, hardware and software environment, depending on what fits best.[1] This does not mean that a single microservice is written in a patchwork of programming languages. While it is almost certainly the case that different components that the service is composed of will require different languages or APIs (example, the web server layer may be in Java or Javascript, but the database may use SQL to communicate to an RDBMS), this is really reflective of a comparison to the monolithic architecture style. If a monolithic application were to be re-implemented as a set of microservices, then the individual services could pick their own implementation languages. So one microservice could pick Java for the web layer, and another microservice could pick a Node.js-based implementation, but within each microservice component, the implementation language would be uniform.
  • Services are small in size, messaging-enabled, bounded by contexts, autonomously developed, independently deployable, decentralized and built and released with automated processes.[8]

A microservice is not a layer within a monolithic application (example, the web controller, or the backend-for-frontend[9]). Rather it is a self-contained piece of business functionality with clear interfaces, and may, through its own internal components, implement a layered architecture. From a strategy perspective, microservices architecture essentially follows the Unix philosophy of "Do one thing and do it well".[10] Martin Fowler describes a microservices-based architecture as having the following properties:[5]

It is quite common for such an architectural style to be adopted for cloud-native applications, and applications using lightweight container deployment. As explained[14] by Martin 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. 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.[15] With microservices, only the microservice supporting the function with resource constraints needs to be scaled out, thus providing resource and cost optimization benefits.

History[edit]

A workshop of software architects held near Venice in May 2011 used the term "microservice" to describe what the participants saw as a common architectural style that many of them had been recently exploring[citation needed]. In May 2012, the same group decided on "microservices" as the most appropriate name. James Lewis presented some of those ideas as a case study in March 2012 at 33rd Degree in Kraków in Microservices - Java, the Unix Way, as did Fred George about the same time. Adrian Cockcroft at Netflix, describing this approach as "fine grained SOA", pioneered the style at web scale, as did many of the others mentioned in this article - Joe Walnes, Dan North, Evan Bottcher and Graham Tackley.[16]

Dr. Peter Rodgers introduced the term "Micro-Web-Services" during a presentation at the Web Services Edge conference in 2005. On slide #4 of the conference presentation, he states that "Software components are Micro-Web-Services".[17] Juval Löwy had similar precursor ideas about classes being granular services, as the next evolution of Microsoft architecture.[18][19][20] "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 service platform "applies the underlying architectural principles of the Web and Web services together with Unix-like scheduling and pipelines to provide radical flexibility and improved simplicity by providing a platform to apply service-oriented architecture throughout your application environment".[21] The design, which originated in a research project at Hewlett Packard Labs, aims to make code less brittle and to make large-scale, complex software systems robust to change.[22] To make "Micro-Web-Services" work, one has to question and analyze the foundations of architectural styles (such as SOA) and the role of messaging between software components in order to arrive at a new general computing abstraction.[23] In this case, one can think of resource-oriented computing (ROC) as a generalized form of the Web abstraction. If in the Unix abstraction "everything is a file", in ROC, everything is a "Micro-Web-Service". It can contain information, code or the results of computations so that a service can be either a consumer or producer in a symmetrical and evolving architecture.

Microservices is a specialization of an implementation approach for service-oriented architectures (SOA) used to build flexible, independently deployable software systems.[24] The microservices approach is a first realisation of SOA that followed the introduction of DevOps and is becoming more popular for building continuously deployed systems.[25]

Service Granularity[edit]

A key step in defining a microservice architecture is figuring out how big an individual microservice has to be. There is no consensus or litmus test for this, as the right answer depends on the business and organizational context. Amazon's policy is that the team implementing a microservice should be small enough that they can be fed by two pizzas.[5] Many organizations choose smaller "squads" - typically 6 to 8 developers. But the key decision hinges around how "clean" the service boundary can be.

On the opposite side of the spectrum, it is considered a bad practice to make the service too small, as then the runtime overhead and the operational complexity can overwhelm the benefits of the approach. When things get too fine-grained, alternative approaches must be considered - such as packaging the function as a library, or by placing the function into other microservices.[citation needed]

Linguistic approach[edit]

A linguistic approach to the development of microservices[26] focuses on selecting a programming language that can easily represent a microservice as a single software artifact. When effective, the gap between architecting a project and deploying it can be minimized.[citation needed]

One language intended to fill this role is Jolie.[27][28]

Technologies[edit]

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 (REST, messaging, ...). In a traditional system most technology choices like the programming language impact the whole systems. Therefore the approach for choosing technologies is quite different.[29]

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

Service mesh[edit]

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. 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.

In a service mesh, the service instances and their sidecar proxies are said to make up the data plane, which includes not only data management but also request processing and response. The service mesh also includes a control plane for managing the interaction between services, mediated by their sidecar proxies. There are several options for service mesh architecture: Istio (a joint project among Google, IBM, and Lyft), Buoyant[31] & others

Criticism[edit]

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

  • Services form information barriers.[32]
  • 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.[5]
  • Testing and deployment are more complicated.[33]
  • Moving responsibilities between services is more difficult.[1] It may involve communication between different teams, rewriting the functionality in another language or fitting it into a different infrastructure.[5]
  • 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.[34]
  • Two-phased commits are regarded as an anti-pattern in microservices-based architectures as this results in a tighter coupling of all the participants within the transaction. However, lack of this technology causes awkward dances which have to be implemented by all the transaction participants in order to maintain data consistency.[35]
  • Development and support of many services is more challenging if they are built with different tools and technologies - this is especially a problem if engineers move between projects frequently.

Cognitive load[edit]

The architecture introduces additional complexity and new problems to deal with, such as network latency, message formats, load balancing and fault tolerance.[36][33] All of these problems have to be addressed at scale.

The complexity of a monolithic application doesn't disappear if it gets re-implemented as a set of microservice applications. Some of the complexity gets translated into operational complexity.[37] Other places where the complexity manifests itself is in the increased network traffic and resulting 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.[38] Various organizing principles (such as HATEOAS, interface and data model documentation captured via Swagger, etc.) have been applied to reduce the impact of such additional complexity.

A comparison of platforms[edit]

Prior to Kubernetes and its ecosystem of tools being developed, implementing a microservice architecture was hard because of the lack of popular frameworks. There are many concerns (see table below) that any microservice architecture needs to address. Netflix developed a microservice framework to support their internal applications, and then open-sourced[39] many portions of that framework. Many of these tools have been popularized via the Spring Framework – they have been re-implemented as Spring-based tools under the umbrella of the Spring Cloud[40] project. The table below shows a comparison of an implementing feature from the Kubernetes ecosystem with an equivalent from the Spring Cloud world.[41] One noteworthy aspect of the Spring Cloud ecosystem is that they are all Java-based technologies, whereas Kubernetes is a polyglot runtime platform.

Microservices concern Spring Cloud & Netflix OSS Kubernetes
Configuration management: configuration for a microservice application needs to be externalized from the code and be retrievable via a simple service call. Spring Config Server, Netflix Archaius both support a Git-repository--based location for configuration. Archaius supports data typing of configuration. Kubernetes ConfigMaps exposes the configuration stored in etcd via services. Kubernetes Secrets supports the service-based secure deployment and usage of sensitive configuration information (such as passwords, certificates, etc.).
Service discovery: maintain a list of service instances that are available for work within a microservice domain. Spring Cloud Eureka allows clients to register to it, maintains a heartbeat with registered clients, and maps service names to hostnames for clients that look up services by service name. Kubernetes Services provide deployment-time registration of instances of services that are internally available within the cluster. Ingress is a mechanism whereby a service can be exposed to clients outside the cluster.
Load balancing: The key to scaling a distributed system is being able to run more than one instance of a component. Load has to be then distributed across those instances via a load balancer. Spring Cloud Ribbon provides the ability for service clients to load balance across instances of the service. Kubernetes Service provides the ability for the service to be load-balanced across service instances. This is not the equivalent of what Ribbon provides.
API gateway: The granularity of APIs provided by microservices is often different than what a service client needs. API Gateways implement facades and provide additional services like proxying, and protocol translation, and other management functions. Spring Cloud Zuul provides configuration-based API facades Kubernetes Service and Ingress resources, Istio, Ambassador are solutions that provide both north-south (traffic into and out of data center) as well as east-west (traffic across data centers or clouds or regions) API gateway functions.
Security concerns: Many security concerns are pushed to the API gateway implementation. With distributed microservice applications, it makes sense to not reinvent the security wheel and allow for policy definition and implementation in components that are shared by all services. Spring Cloud Security addresses many security concerns through Spring Cloud Zuul The Kubernetes ecosystem provides service meshes like Istio, which are capable of providing security through their API gateway mechanisms.
Centralized logging: It is important to have a centralized log gathering and analysis infrastructure to manage a plethora of services – many of which are operating in a distributed fashion. ELK Stack (Elasticsearch, LogStash, Kibana) EFK Stack (Elasticsearch, Fluentd, Kibana)
Centralized metrics: A centralized area where the health and performance of the individual and overall system is essential to proper operations. Spring Spectator & Atlas Heapster, Prometheus, & Grafana
Distributed tracing: Per-process logging and metric monitoring have their place, but neither can reconstruct the complex paths that transactions take as they propagate across a distributed system. Distributed tracing is an essential tool for a microservices platform. Spring Cloud Sleuth Hawkular
Resilience and fault tolerance: Distributed systems must be capable of auto-routing around failures, and be capable of routing requests to the service instance that will provide an optimum response. Spring Hystrix, Turbine, & Ribbon Health check, service meshes (example: Istio)[42]
Autoscaling and self-healing: Distributed systems respond to higher load by scaling horizontally: the platform must detect and auto-respond to such conditions. Furthermore, the system needs to detect failures and attempt auto-restarts without operator input. - Health check, self-healing and auto-scaling
Packaging, deployment and scheduling: Large-scale systems require robust package management, and deployment systems to manage rolling or blue-green deployments, and rollbacks if necessary. A scheduler helps determine which particular execution node a new set of services can be deployed to based on current conditions. Spring Boot, Apache Maven. The Spring Cloud system does not have a true scheduler. Docker, Rkt, Kubernetes Scheduler & Deployment, Helm[43]
Job management: scheduled computations disconnected from any individual user requests Spring Batch Kubernetes Jobs and Scheduled Jobs
Singleton application: run specific services as a single instance of it within the entire system Spring Cloud Cluster Kubernetes Pods

Implementations[edit]

See also[edit]

References[edit]

  1. ^ a b c d Chen, Lianping (2018). Microservices: Architecting for Continuous Delivery and DevOps. The IEEE International Conference on Software Architecture (ICSA 2018). IEEE.
  2. ^ Richardson, Chris. "Microservice architecture pattern". microservices.io. Retrieved 2017-03-19.
  3. ^ Chen, Lianping; Ali Babar, Muhammad (2014). Towards an Evidence-Based Understanding of Emergence of Architecture through Continuous Refactoring in Agile Software Development. The 11th Working IEEE/IFIP Conference on Software Architecture(WICSA 2014). IEEE. doi:10.1109/WICSA.2014.45.
  4. ^ Balalaie, Armin; Heydarnoori, Abbas; Jamshidi, Pooyan (May 2016). "Microservices Architecture Enables DevOps: Migration to a Cloud-Native Architecture". IEEE Software. 33 (3): 42–52. doi:10.1109/ms.2016.64. hdl:10044/1/40557. ISSN 0740-7459.
  5. ^ a b c d e Martin Fowler. "Microservices". Archived from the original on 14 February 2018.
  6. ^ Newman, Sam (2015-02-20). Building Microservices. O'Reilly Media. ISBN 978-1491950357.
  7. ^ Wolff, Eberhard (2016-10-12). Microservices: Flexible Software Architectures. ISBN 978-0134602417.
  8. ^ a b Nadareishvili, I., Mitra, R., McLarty, M., Amundsen, M., Microservice Architecture: Aligning Principles, Practices, and Culture, O’Reilly 2016
  9. ^ "Backends For Frontends Pattern". Microsoft Azure Cloud Design Patterns. Microsoft.
  10. ^ Lucas Krause. Microservices: Patterns and Applications. ASIN B00VJ3NP4A.
  11. ^ Grails Founder: What Java Developers Don’t Know About Memory Can Cost Them Money in the Cloud Forbes Retrieve 9 January 2019
  12. ^ Designing microservices: Continuous integration Microsoft Retrieved 9 January 2018
  13. ^ Josuttis, N. (2007). SOA in Practice. Sebastopol, CA, USA: O'Reilly. ISBN 978-0-596-52955-0.
  14. ^ Martin Fowler. "Microservice Prerequisites".
  15. ^ Richardson, Chris (November 2018). Microservice Patterns. Chapter 1, section 1.4.1 Scale cube and microservices: Manning Publications. ISBN 9781617294549.
  16. ^ James Lewis and Martin Fowler. "Microservices".
  17. ^ Rodgers, Peter. "Service-Oriented Development on NetKernel- Patterns, Processes & Products to Reduce System Complexity Web Services Edge 2005 East: CS-3". CloudComputingExpo 2005. SYS-CON TV. Retrieved 3 July 2017.
  18. ^ Löwy, Juval (October 2007). "Every Class a WCF Service". Channel9, ARCast.TV.
  19. ^ Löwy, Juval (2007). Programming WCF Services 1st Edition. pp. 543–553.
  20. ^ Löwy, Juval (May 2009). "Every Class As a Service". Microsoft TechEd Conference, SOA206. Archived from the original on 2010.
  21. ^ Rodgers, Peter. "Service-Oriented Development on NetKernel- Patterns, Processes & Products to Reduce System Complexity". CloudComputingExpo. SYS-CON Media. Retrieved 19 August 2015.
  22. ^ Russell, Perry; Rodgers, Peter; Sellman, Royston (2004). "Architecture and Design of an XML Application Platform". HP Technical Reports. p. 62. Retrieved 20 August 2015.
  23. ^ Hitchens, Ron (Dec 2014). Swaine, Michael (ed.). "Your Object Model Sucks". PragPub Magazine: 15.
  24. ^ Pautasso, Cesare (2017). "Microservices in Practice, Part 1: Reality Check and Service Design". IEEE Software. 34 (1): 91–98. doi:10.1109/MS.2017.24.
  25. ^ "Continuous Deployment: Strategies". javacodegeeks.com. Retrieved 28 December 2016.
  26. ^ Claudio Guidi (2017-03-29). "What is a microservice? (from a linguistic point of view)".
  27. ^ Jolie Team. "Vision of microservices revolution".
  28. ^ Fabrizio Montesi. "Programming Microservices with Jolie - Part 1: Data formats, Proxies, and Workflows".
  29. ^ Wolff, Eberhard (2018-04-15). Microservices - A Practical Guide. ISBN 978-1717075901.
  30. ^ Swart, Stephanie (14 December 2016). "Eclipse MicroProfile". projects.eclipse.org.
  31. ^ "What's a service mesh?". Buoyant. Buoyant. 2017-04-25. Retrieved 5 December 2018.
  32. ^ Stenberg, Jan (11 August 2014). "Experiences from Failing with Microservices".
  33. ^ a b "Developing Microservices for PaaS with Spring and Cloud Foundry".
  34. ^ Tilkov, Stefan (17 November 2014). "How small should your microservice be?". Innoq. Retrieved 4 January 2017.
  35. ^ Richardson, Chris (November 2018). Microservice Patterns. Chapter 4. Managing transactions with sagas: Manning Publications. ISBN 978-1-61729454-9.
  36. ^ Pautasso, Cesare (2017). "Microservices in Practice, Part 2: Service Integration and Sustainability". IEEE Software. 34 (2): 97–104. doi:10.1109/MS.2017.56.
  37. ^ Fowler, Martin. "Microservice Trade-Offs".
  38. ^ "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."
  39. ^ Netflix OSS, Git Hub
  40. ^ Cloud, Spring
  41. ^ "Spring Cloud for Microservices Compared to Kubernetes", Developers, Red hat, 2016-12-09
  42. ^ Managing microservices with the Istio service mesh, Kubernetes, May 2017
  43. ^ The Kubernetes Package Manager, Helm

Further reading[edit]