In the microservice approach, there are many aspects to be taken care of, and at the same time, we need to keep in mind that some of them are also used in the monolithic approach. The most vital ones are as follows:
- Service Discovery,
- API Gateway (Routing),
- Server Side Load Balancing,
- Client Side Load Balancing,
- Circuit Breaker,
Simply put, it is a service that allows new services to be registered, and it also shares information about registered users. These are often implementations of the 'key-value' pattern, which requires high reliability and speed. A base service that allows to balance the load through all available machines and, consequently, the automatic scaling of our applications. The most popular Service Discovery implementations include:
* which is based on ‘Amazon Route 53, AWS Lambda, and ECS Event Stream’
Service Discovery based on Eureka Server
The simplest ways of launching and starting the work with Eureka:
* Spring Cloud Eureka
- run Docker image
- creating a simple Spring Boot project with dependencies to ‘Eureka Server’. Let's go step by step through the sources necessary to create and run the ‘Eureka Server’ project by ourselves.
The main class source code (and the most important annotation in this example
- Properties to define in 'application.properties'
In such a situation we should have the Eureka website available on: `http://host:8761`. The main service looks as follows:
It contains basic information such as: current time, replicas (registered, available, unavailable), i.e. the entire so-called server status, and basic information, i.e. memory use, available memory, the name of the environment in which it is running, the number of available processors, as well as the time of work since it was run. Of course, from our perspective the most important aspect is the list of available services.
Client Service Discovery based on Spring Boot Web
Naturally, we will move on to simple services that will become registered in our Service Discovery.
- A sample service code where the most important, from our perspective, is annotation ‘@EnableDiscoveryClient’:
- And `application.properties`
API Gateway is a starting point of our application that redirects requests to relevant services in our environment. To sum up, it provides the public API.
The most popular implementations are shared by cloud providers. Of course, nothing stops you from using a different implementation, e.g.:
- Zuul Netflix
- Amazon API Gateway
- Azure API Management.
API Gateway – based on Zuul Netflix
Zuul is a service running on a Java virtual machine, acting as a router as well as Server Side Load Balancing. Thanks to filtering: pre, route, post, error.
It enables many functionalities, such as:
- injecting data (e.g. to headlines).
Client Side Load Balancing – Ribbon
Ribbon can be used without dynamic information about available servers. Then, we are able to define the necessary properties in the 'application.properties' file with information between which servers the client should balance the load. Configuration example:
In our example, we want `Ribbon` to work properly in the microservices architecture, which assumes a dynamic number of instances of a given service. The customer should be able to obtain this information while working.
- Example `application.properties` of Ribbon being registered in ‘Eureka Serwer’ and refreshing the list of instances of the service that is of interest to it.
- The configuration used in the project:
- The class starting with the Client:
API Gateway – Routing
The starting point for our architecture. It redirects requests to relevant services. In our case, it will be the `Zuul` open-source project. Thanks to the filter mechanism, it is able to filter input traffic, allow easy monitoring and ensure security and authentication. It must provide high performance and scalability. For instance, by using cloud environments, we have equivalents. And so AWS has a dedicated API Gateway that provides similar functionalities.
In order to illustrate how routing works, we will build two different simple services and the API Gateway based on `Zuul` example.
The source code of the first service and `application.properties`:
The source code of the second service and `application.properties`:
The most important of our components - Zuul service and its `application.properties`
From now on, our requests will be redirected to the right service through a specific part of the URL.
Server Side Load Balancing
In order to illustrate it, we will use the technology stack discussed above: Eureka, Zuul and Spring Boot Web.
We want to get the following architecture (screen below), in which sites performing operations register in Service Discovery (Eureka). API Gateway (Zuul) inquires and refreshes information about the available instances. In order to make everything work, you need to create a customer who will query our services via API Gateway. The only difference to the previous approach is the addition of Service Discovery, Eureka Service in our case, which provides information about the registered sites.
The created architecture will allow easy scaling, still manual in this case. However, by means of integration with the orchestrator, e.g. Kubernetes, Docker Swarm or the cloud, it is easy to enable autoscaling depending on the system load.
There are certainly better and newer solutions for playing with microservices. It is best to work using a cloud solution, e.g. Amazon Web Services or Microsoft Azure. However, in the technology stack presented above, everything is free of charge – so we do not have to worry about unforeseen costs resulting from providing our credit card details.
The entry threshold seems quite small for a Java programmer. And the fun itself does not require strong equipment. In fact, all I have to say now is to wish you a lot of fun.