Microservices – architecture for service-driven business models?
It’s a word that has been on everyone’s lips for quite some time: Microservices. Above all else, microservices are something that the world of business should benefit from.
Volatile markets and new trends that have been around for some time such as Cloud Computing, Big-Data, IoT etc. are presenting companies with challenges that need to be overcome quickly and successfully. The promise of “small-scale services” of this kind, or “microservices”, is to be found in a brand new dynamic in the area of software development and deployment which is made possible by microservices. In brief: Both the world of business and users can be happy – after all, microservice architectures open up brand new opportunities: Accelerated development models, a faster time-to-market, increased flexibility, more independent teams, etc. – and on the user side, a great new world of services and apps is emerging. Buzzwords, marketing bingo, mantra or promises of salvation? What is behind the microservices paradigm?
What are microservices?
Let us approach the answer colloquially, after all, we want to explain the idea of microservices in a simple and comprehensible way: Microservices are an architectural concept, a paradigm of application development. This concerns the way in which the applications are developed. Extensive application software, which is implemented conceptually via microservices, consists of smaller, independent programs. Each of these programs completes precisely one task – true to the Unix philosophy: “Do one thing well.” A philosophy that has been pretty successful for the world of software, it has proven itself in userland/userspace in many incarnations and manifestations up to the present day – since the early 1970s, from the origins of Unix and subsequent BSDs, via Nextstep and Darwin, through to Linux.
These programs then communicate with each other as microservices via well-defined APIs (interfaces). As interfaces ideally behave agnostically towards the programming languages that are used, this provides development teams with new scope for action. At the same time, the microservices paradigm also forces the individual microservices to be independent of each other. That has consequences: A single microservice will then function independently of all the other services or not at all. But that doesn’t matter. After all: If the latter occurs, this failure will not bring all the other services to a standstill. It’s an inconvenience, but it’s good enough. A software system that conceptually consists of many of these microservices can rightly be called a microservices architecture.
Microservice vs. monolith: the difference metaphorically illustrated
Let us address the matter with an image. As with house building, there are a variety of ways in which IT systems are designed and built. This allows for a clear illustration of the difference between a microservice and a monolith.
The monolithic approach
To simplify matters, imagine a detached family house: Depending on the requirements, the architect is able to build a classic house in a rectangular shape. The architecture is predetermined, everything has its fixed, pre-defined place. The windows, doors, walls, cellars and floors… – a monolithic system, a rigid structure. If the residents want to change something after several years, they are faced with a variety of problems: Can I really tear down this or that wall or build new walls in the attic and thus rooms for various purposes, for example, or would I put the structure at risk? In software development, this concept corresponds to the monolith (see below).
The micro-service approach
However, a homeowner can also opt for a flexible, modular design right from the start. And they do so in anticipation that their needs will change in the future. In the first step, the builder considers building the house from individual containers. As soon as his initial thoughts, he remembers not to make use of rectangular containers – but of containers in a hexagonal format, similar to the honeycombs in a beehive. The reason quickly becomes clear. Building a house using hexagonal containers, for example, means that the builder doesn’t just stack additional containers side by side or on top of one another. On the contrary, for example, he can remove a container from the third floor later without this adversely affecting the fourth or fifth floor. This approach is equivalent to a microservices architecture.
This very simple representation can also be applied to IT and software systems. The classic house would roughly correspond to the monolithic architecture, the container house to the microservice architecture. Both have advantages and disadvantages.
Examples of microservices – specific illustration of the division of labor
Let us take the example of a website for a parcel and letter-sending service. On this website, you can find numerous examples of microservices:
- Tracking of the shipment,
- Calculation of postage fees,
- Online franking,
- Required location for receiving the shipment etc.
And all, of course, as services for private customers and business customers. But just because the tracking of the shipment fails, for example, does not mean that all the other microservices are affected and are no longer available. These services are good examples of a microservice architecture. Many of the services can be accessed via a rest API, for example; it goes without saying that microservices can also be used via an app for iOS and Android. These are all signs that could point to a microservices architecture. Other practical examples of Microservices are used by the companies Twitter, eBay, Spotify, Netflix and Zalando etc.
Monolithic architecture – traditional but not outdated
To be able to understand microservice architectures at all, it is firstly worthwhile to take another look at standard, monolithic architectures. Their structure can be thought of as one big application, a block where all the necessary code is collected. Although the functions provided are modularized, they are neither independent of each other nor of the entire block. The monolith only exists as a bloc. The software is written, compiled and deployed as a unit, i.e. distributed on user PCs or servers. A particularly clear example is the Amazon web shop of the past. This was realized several years ago as a monolithic application (300 to 500 MB in size, compile time up to 10 hours). This wasn’t easy to maintain and it wasn’t easy to add new features, not to mention the deployment.
Advantages of microservices at a glance
Where flexibility and speed are currently important in the world of business, a microservice architecture has a special role to play. The initial workload required to plan, develop and finally roll out a microservice architecture should not be underestimated. It is certainly greater than in comparison with a monolithic application. However: Once the architecture is in place, many of the advantages of microservices can be used. In this respect, trying out new business ideas “just like that”, for example, no longer presents a company with problems.
On this basis, it would be easy to accelerate the process of putting business ideas or goals to an initial reality test via so-called “minimum viable products” (MVPs). This is one of the advantages of microservices. The same applies to subsequent, rapid iterations of error corrections, adjustments and improvements to the first MVPs as a microservice – which is ideal for service-driven architectures. This is just one of the advantages of microservices though. Now, let us take a look at what other advantages microservices offer and why this is the case.
Microservices – multifaceted independence
The key features, characteristics and ultimately the advantages of microservices as well as of a microservices architecture consist in their independence from various points of view.
Technological freedom of choice 1: Microservices REST-Api
The programming language in which a client is written, and which interacts with the microservice, can be freely chosen. Because requests are often received via a REST API (REpresentational State Transfer), any programming language that supports REST can be used on the client side. REST is based on the HTTP verbs GET, PUT, POST/PATCH and DELETE, and is a very old network protocol. As far as the programming language for the clients is concerned, the choice is therefore yours. After all, whether a client for a microservice is Python-based or in any other language, is actually irrelevant as long as the client can handle REST and can address the REST API. The decision on the programming language in which a client for a microservice is written therefore depends on other factors.
Which protocols can still be used to address microservices on the client side?
REST is not the only API/protocol with which microservices can be addressed from the client. Some of the following examples are based on REST, extend it, and are also suitable for microservices:
- Open Data Protocol (oDATA): A protocol from Microsoft, also HTTP-based
- WebSockets: For communication in real-time, through a persistent connection between the client and service, without HTTP overhead and avoiding “long-polling”
- GraphQL: Query and API description language. Introduced by Facebook.
- RESTful API Modeling Language (RAML): Description language of APIs and their use.
- OpenAPI Specification: Standard for describing REST-compliant APIs; promoted by the OpenAPI initiative
Technological freedom of choice 2: Independence of the chosen programming language
There is also added freedom when implementing microservices. In principle, each microservice can be implemented in a different programming language. The decision on this must be made by the respective team that will implement and support the microservice. This also gives the teams considerably more freedom. After all, the question of which libraries, SDKs and databases etc. are chosen for a microservice is also decided by the teams. This is the only way to enable and maintain the independence and flexibility of microservices and to create the conditions for the accelerated deployment of the microservices (in this respect, also refer to Docker).
How do microservices actually communicate with one another?
After the client has transmitted data to a microservice via REST, the question that arises is what happens to it now? Within a microservice architecture, it is pretty obvious that the data also communicates with each other via APIs that are based on REST.
There are various approaches to this as well. Firstly, the most important things: The goal should always be the achievement of an asynchronous communication between the various microservices – in short: the use of ASYNC. Without going into further details, asynchronous communication at this point means, for example, that Microservice A sends its call to Microservice B – without waiting for the outcome of this request. At this point, A “only” receives the response code 202 (accepted), which is transmitted via HTTP header. A now “knows” that its request has been received and is being processed – with the outcome that the resources are freed up at A and other advantages are created, such as a lower degree of latency within the microservices architecture. The following protocols are then used as examples:
- RESTful (see above)
- OData (see above)
- Google Remote Procedure Calls (gRPC)
- Remote Procedure Calls (RPC)
The use of message queues, which to a certain extent constitute a separate message service, e.g. with RabbitMQ or Kafka, takes this ASYNC idea to the extreme. RabbitMQ, for example, works with special message protocols (AMQP, MQTT, STOMP). In this respect, correlation IDs are used to track which specific response message relates to which request.
Independent deployment of the microservices
Ideally, on the basis of previous considerations and decisions, the option to roll out a microservice independently of all the other services in the microservice architecture is now available. This describes the central strengths and characteristics of a microservice. Precisely because a microservice only completes one task, it ideally has a comparatively small code base, and can be rolled out and started comparatively quickly – and this service does not affect any other service in the microservices architecture. All other microservices remain available during the deployment and do not need to be re-deployed. To stay with the above example, the customer can continue to frank their shipments even though the microservice for the tracking of the shipment is currently being rolled out again.
This approach is therefore perfect for service-driven architectures. Useful to know: This division of microservices is also reflected in the responsibilities of the teams. Accordingly, DevOps teams can be formed, each of which specializes in a specific microservice – in this respect, the “Do one thing well” approach also applies to the teams (see: DevOps).
In comparison with a monolithic system, the advantages of a microservice architecture are obvious: Once the monolith is in operation, corresponding maintenance times must be scheduled for changes. After all, the structure means that the system is always affected entirely and may have to be restarted several times to test whether the changes in the code have the required effect. With a microservice architecture, this is not necessary. These new starts illustrate a further problem with monolithic structures: The more frequent the changes and the greater the amount of code, the slower the development process – and frequent changes are highly desirable when using MVPs via microservices, for example.
Microservices: Finely grained scalability
With the described segmentation, however, further advantages of the microservice architecture can be achieved in addition to the independent deployment. Once rolled out via Docker (see below), for example, managing the scalability of the individual services does not present the teams with any major challenges. If a microservice takes up too much CPU time or allocates too much memory, this can be compensated for pretty quickly by a load balancer and an additional microservice. With a monolith, the system always has to be scaled manually in its entirety.
All wrapped up: Microservices with Docker
Once packaged in narrow Docker containers (see below), nothing stands in the way of the rapid deployment of individual microservices. Due to the increased popularity of and enthusiasm for microservice architectures, in recent years, a toolchain for the software delivery process has developed.
For this purpose, various technologies are available to the individual microservices teams. Their goal: To automate the deployment process to a large extent and thereby simplify it. Saving time and avoiding mistakes is the motto.
Dockers and Kubernetes
Given the complexity of services which can have a microservices architecture, the DevOps team naturally requires the appropriate tools for the administration. Kubernetes (K8s) is one such tool. Imagine the initial situation: The basis of the architecture consists of several Docker containers and numerous hosts, i.e. individual physical or virtual computers. Using Kubernetes, the Docker containers can now be grouped, combined into pods and rolled out: on a node (vhost or physical computer), for example. In this context, the advantages of Kubernetes are the comparatively simple and rapid deployment of the microservices. At the same time, K8s offer a convenient solution for managing a microservice architecture with hundreds of microservices, for example: Balancing, scaling and monitoring peak loads. Dashboards (WebUI) and various command line tools are the tools of choice for managing the services on-premises, hybrid or in the public cloud – so they are perfect for DevOps managers to orchestrate the microservices. (Kubernetes is open source (Apache License 2.0))
Each new iteration of a microservice can then be rapidly introduced into the staging or production environment with the bug fixes and new enhancements, with low risk and little manual workload. Even for this area of software development, new methods and team structures and responsibilities are made use of, as wells as a new corporate culture, to a certain extent.
What is Docker?
Docker is considered a lightweight virtualization solution. Containers are the key element of Docker. Within these Docker containers, all the components belonging to a microservice (code, system tools and -libraries, etc.) can be zipped in an IMG file. The resources used on a computer are separated cleanly by Docker containers. As a container, the virtualization solution uses the kernel of the host, and in contrast to VirtualBox, VMware or XEN, does not come with its own kernel / operating system. Less RAM and time required to start the microservices are the result.
Trio Infernale: Continuous delivery, DevOps and microservices
To turn a noble goal into reality, it has proven to be best practice to make use of DevOps teams and the Continuous Delivery method. In combination with microservices, this trio constitutes a product of its age, with the keywords of “volatile markets/new challenges for companies/rapid provision of stable services”. Why is it that the requirements and goals outlined above can be achieved by this trio of microservices, DevOps and continuous delivery?
The word DevOps is a combination of the short forms of “Dev” for development and “Op” for operations – in this case: for IT operations. Software development, system administration and the deployment of microservices are now being considered simultaneously. The goal is a close cooperation between development and operation for the rapid provision of smoothly functioning microservices. The expertise of DevOps teams is to be found in software development AND in terms of IT systems and system infrastructure. In this way, DevOps combines the best of both worlds. In combination with the Continuous Delivery method, DevOps uses a tool chain, specific techniques and processes that automate and optimize the software deployment in terms of the software quality, flexibility and speed.
Releasing software is too often an art; it should be an engineering discipline, David Farley
Microservices revisited – the holy grail?
Of course, the devil is often in the detail. And at first glance, achieving a service-driven business model by implementing microservices to solve business requirements certainly seems a promising prospect. However, when it comes to whether a microservice architecture can be useful at all, a lot depends on the specific situation, the problem and the objective. Therefore, here is a brief comparison of the advantages and disadvantages of microservice architectures:
Advantages of microservice architectures
- A smaller code basis means less complexity within the individual microservices.
- The communication workload between the individual project teams is reduced.
- Continuous delivery
- Better scalability: Individual services can be scaled several times
- High rate of fail-safety
Disadvantages of microservice architectures
- Complexity of the entire system of microservices
- Sophisticated deployment of the services
- Unexpected latency between the microservices in the distributed system
- Each microservice is an independent system; this also applies to the deployment process; resources must be kept available; high-cost
- High workload for the migration of old systems to the new microservice architecture