The word "microservices" has been around for the past few years. The technology is actively developing, people talk about it at online conferences, and we write them ourselves every day. Once upon a time, a new approach has already become a routine. But as a Java architect, I am interested in what the code was like before, how it changed, what methods of execution are popular now and will be used in 2021: asynchrony, containers, FaaS.
This is how this post was born in two parts, which I prepared for Habr based on my articles on the BellSoft blog and the Joker 2020 round table , where we discussed the future of Java. The improvement of the ecosystem for backends that is relevant today cannot exist without understanding how to create microservices: write from scratch or cut out of monoliths with a scalpel? I propose in the first part to talk about their essence, and in the second - to decompose the microservice container into layers and look at the contribution of each layer.
The main advantage is in the structure
The vast majority of materials on microservice architecture compare it to monoliths in terms of structure. How the components work as a whole or in isolation. Microservices are independent of each other and can exchange data over the network via arbitrary protocols, such as the REST API. What does it give us? At a minimum, the freedom to choose any tools, without looking back at ESBs, schema restrictions and compatibility subtleties. Virtualization and containerization are also evolving, and now tiny containers with Alpine Linux allow you to run many components at once on previously dedicated hardware.
Let's take a simple service like booking a ticket or recharging an account. Even before the advent of microservices, the CRUD approach was used to manage the lifecycle of a data object in such systems. But all the functionality that provides CRUD operations for some entity can be easily isolated. Then you can separately deal with scaling, access control and interaction in general, for example, through REST.
Everything seems to be fine, what's the catch?
Problems and solutions
Different parts of a monolithic application run in shared memory, and all requests are sent to the same physical server. Microservices communicate with each other through protocols, and this gives rise, for example:
difficulty in managing network traffic and latency;
failures of requests and other errors;
the need to serialize data and encrypt connections.
, API Kafka/Redis/RabbitMQ , . Kafka DevOps.
, , . . , , โ . - .
:
(Kafka, Kinesis);
, service mesh (Istio, OSM);
.
โ :
, , :
, . streaming platform (, Kafka) , .
, . , . , , .
Service mesh (ยซc ยป) . , , Sidecar.
, JVM, , .
. , , Docker- .
-, , . , .
- . . , โ SOA.
. . , โ . , , REST.
Java? , . Java EE 20 . : , XML javadoc ; ; Java 5. . Java EE.
, Java EE (, JNDI), , , . Web 1.0 Web 2.0, . .
Container dependency injection
ยซ ยป. , . ยซ ยป โ . . , : trailing lambdas Kotlin Ktor; data- , Java 14 record- ( Lombok).
. , /. , , , , . IDE, , . โ .
Contexts and Dependency Injection (CDI). CDI Java EE JSR 299/365 Weld, WildFly. โ (Inversion of Control, IoC).
: , , ( Spring Data) HTML. . โ , . , Convention over Configuration ( ยซ ยป), IoC- , BeanFactory Spring. .
As I promised in the introduction, this post has become a small excursion into the history of microservice architecture - after all, without it, you can't go anywhere. We are working with great technology that is 20+ years old, but still feels modern. This is because the methods are in demand and live, and do not turn into legacy.
In the second part, I will analyze in detail the layers of the microservice container, explain what the correct choice of runtime affects, and tell you how to reduce resource consumption to a minimum.