Microservice (also known as microservices architecture) is a type of software that allows for applications to be built and maintained using smaller components that work together. It is related to service-oriented architecture (SOA) and enables applications to be scalable. The components are separately maintained, so they can be developed independently. If an issue should arise, it is isolated in that singular component rather than affecting the entire application.
The software is being used by companies such as Netflix, Spotify, ASOS, and Expedia.
Applications used within microservices architecture have core functions which are known as "services." Services include search engines, product recommendations when using e-commerce, authentications, notifications, and online carts. Each of the services has its own codebase, infrastructure, and database. In order for the services to function together, they communicate through application programming interfaces (APIs) or messaging queues.
It is common for microservices architectures to be adopted for cloud-native applications, serverless computing, and applications using lightweight container deployments. In the deployment, and because of the large numbers of services, decentralized continuous delivery and DevOps with holistic service monitoring are often necessary to develop, maintain, and operate applications.
In microservice applications, independent services prefer to reuse code and accept data duplication in order to improve decoupling. The services do not want dependencies in the application running and accepting the resultant data duplication. This data duplication can increase a service's complexity, but it also results in benefits in agility and performance in a service and in the larger application. Communication and synchronous calls can introduce real-time dependencies which may result in a loss of resilience in microservice applications. These calls can also cause latency.
Key characteristics
In a decentralized environment, where each service is independent and serves a single or limited purpose, communication amongst the services becomes crucial to the overall operation of an application. And, with the proliferation of services, the call and response between services add latency. To deal with this, most microservices architectures work to keep calls to a minimum, optimizing code to reduce communications. It is generally considered best for microservice communication if the back-end system uses asynchronous, message-brokered approaches to communication. While front-end can benefit from synchronous communication and a synchronous communication system for the front-end to back-end communication. Although, with increased complexity in the microservice architecture, asynchronous communication is considered to work best.
Communication protocols and methods
Containers offer a place for microservices architecture to be housed and are closely associated with microservices. Due to the lack of an operating system and the container being smaller and lighter than a traditional virtual machine, the container can spin up and down more quickly and offer an attractive place for the smaller services in a microservices architecture. It is possible to build microservices without using containers, which tends to increase development and testing.
Microservices often communicate through APIs. Though services can communicate directly in some cases, API gateways are often used as an intermediary layer, especially as the application grows. An API can also act as a proxy by routing requests and dispersing requests amongst various services. The API can offer additional security and authentication to the application.
Along with APIs and API calls, which help services establish state and be aware of state, messaging and event streaming can broadcast changes to state and allow other interested services to listen for those changes and adjust accordingly. Combining microservices with event-driven architecture can help build distributed, scalable, fault-tolerant, and extensible systems.
Serverless architectures take some of the cloud and microservice patterns to a logical conclusion. In the case of serverless architectures, a unit of execution is not a small service, but a function, and often a few lines of code. The line which separates serverless functions from microservice is blurry, but functions are often understood as smaller than a microservice.
This architecture differs from a monolithic software architecture, in which an application is built as a single unit. These applications are often built in three main parts: a client-side user interface, a database, and a server-side application. This server-side application is a monolith, a single logical executable, and any changes to the system involve building and deploying a new version of the server-side of the application. Frustrations from the difficulty in change cycles and scaling for monolithic applications have led to microservices architecture.
In the case of an organization which chooses to migrate from a monolithic architecture to microservices, there is a process of decomposition and incremental change patterns to move towards a microservices architecture. This is done by recognizing the key components and logical models in the existing monolithic architecture. These domain boundaries, often called bounded contexts, are the units of decomposition. In understanding these individual components, there is also a need to understand how the unique pieces function and their dependencies. From these understandings and bounded contexts, the individual services of the microservices architecture can be built.
While the microservices architecture is related to service-oriented architecture (SOA), it also differs in a few ways. One difference is communication protocols: for microservices architecture, each service is developed with its own communication protocol; for SOA, each service must share a common communication mechanism called an enterprise service bus (ESB). The ESB can become a point of failure for SOA architectures and sow an entire application. SOAs, through their use of common architecture throughout the services, offer simplified development and troubleshooting. However, these services also tend to operate slower than microservices architectures, which favor duplication over sharing.
There are key benefits to the microservices architecture. Each smaller service is independent, which allows an application to continue functioning in the case of a fault in a single service. And again, with the services being separate, the task of fixing any faults or updating any parts of the whole application is done easier and with less interruption to the whole application. Each component service is also capable of being built on individual technology stacks best suited for the required functionality, rather than the standardized approach taken in monolithic applications.
Further, with code updates being easier, components of the whole microservices architecture can be scaled independent of one another, which can reduce the overall cost associated with having to scale entire applications due to a single feature facing too much load. Microservices architecture also allows developers to code for different services in different languages, and offers easier integrations and deployments.
With the benefits, there are also challenges to microservices architecture. With the distributed deployment, testing can be complicated. This increases with the number of services, which can also lead to information barriers. And, with size, the role of developers increases as they work to mitigate fault tolerance, network latency, and the variety of message formats and load balancing. Integration and management of services can be difficult, especially with a proliferation of programming languages. As well, in use cases where more services without distributed transactions can require increased communication and cooperation amongst service development teams.
In a microservices environment, changing responsibilities between services is more difficult, can include rewriting the functionality in another language, or involve fitting it into a different infrastructure. This can be made more difficult when services are built with different tools and technologies. Some of the resulting complexity of a microservices architecture can be translated into operational complexity, including an increase in network traffic that can result in slower performance. Also, the larger the overall application architecture, the greater the number of interface points to access a respective ecosystem. The architectural complexities can be mitigated with the use of an organizing principle in the microservice.