Session 5.1: Microservices discovery - Eureka
1. Clone the following repository
$ git clone https://github.com/M-Gharib/ESI-W5.git
Note: if you want to create a new Spring Boot project from scratch, you need to install the following dependencies for both the Product service and Inventory service:
- Spring Web;
- Spring Data JPA SQL;
- PostgresSQL Driver SQL;
- Lombok
- Spring Reactive Web;
- Validation I/O
- Eureka Discovery Client.
- Cloud Loadbalancer
For the Discovery service, you need to install the following dependencies:
- Lombok
- Eureka Server
The project you cloned is composed of three different Spring Boot projects that represent two different microservices (the same as last week), and another service to work as a discovery server. In what follows, we will create the discovery server and register the other two services with it.
Enabling and starting the Eureka Service Registry
Service Discovery is one of the key tenets of a microservice-based architecture. Trying to hand-configure each client can be difficult, time-consuming, and error-prone. To solve this problem, Netflix has developed Eureka
, which is a Service Discovery Server and Client.
1. Uncomment the configurations in application.properties
of the discovery-server
service
#eureka.instance.hostname=localhost #eureka.client.register-with-eureka=false #eureka.client.fetch-registry=false #eureka.instance.preferIpAddress=true #server.port=8761
2. Uncomment the @EnableEurekaServer
annotation above the main class of the DiscoveryServerApplication
//@EnableEurekaServer public class DiscoveryServerApplication { public static void main(String[] args) { SpringApplication.run(DiscoveryServerApplication.class, args); } }
3. Run the DiscoveryServerApplication
4. The discovery server should run on port 8761 as defined in application.properties
. Visit http://localhost:8761/, and you should see EUREKA, but if you checked you will see no instances available under Application.
Enabling and starting a Eureka Discovery Client
5. Uncomment the configurations in application.properties
of the product-server
service
#eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka #eureka.instance.preferIpAddress = true
6. Uncomment the @EnableDiscoveryClient
annotation above the main class of the ProductServiceApplication
@SpringBootApplication #@EnableDiscoveryClient public class ProductServiceApplication { ...
7. Run the ProductServiceApplication
, within 30 seconds, it will register itself with the discovery server. However, it will appear as Unknown
(shown in the figure) since we did not give it a name.
8. To solve this problem, add a name to the product-service
by adding the following snippet to the application.properties
of the product-server
spring.application.name=product-service
9. Run the ProductServiceApplication
again, and it should register itself with the discovery server under the given name
10. In RestClientFile.rest
, try to send the following request, why it is not working?
### Get a product with quantity http://localhost:8082/api/productquantity/02
11. Follow the previous steps to enabling and starting a Eureka Discovery Client for the inventory-service
, name it inventory-service
. When you are done, both services should be registered with the discovery service
12. In RestClientFile.rest
, try to send the following request again, it will not work.
### Get a product with quantity http://localhost:8082/api/productquantity/02
13. Modify the mapToProductQuantityDto
function in ProductService.java
, as follows:
.... //.uri("http://localhost:8083/api/inventory/{code}", product.getCode()) .uri("http://inventory-service/api/inventory/{code}", product.getCode()) ....
14. Try to send the following request in RestClientFile.rest
again, it will not work again.
### Get a product with quantity http://localhost:8082/api/productquantity/02
15. To make the previous request work, uncomment the @LoadBalanced
annotation before the getWebClientBuilder
in the ProductServiceApplication
class, as follows:
//@LoadBalanced public WebClient.Builder getWebClientBuilder() { return WebClient.builder(); }
Client-side load balancing
16. To enable a client-side load balancing for a service you just need to change its port to 0
in its application.properties
. When the port is changed to 0
, Spring Boot will assign an available port for each new instance of the service. Moreover, you need to assign IDs to the instances as follows:
... #inventory-service server.port=0 #server.port=8083 ... eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id} ...
17. Try to run several instances of the inventory-service
after changing its port to 0
, and check how they will be registered with the discovery service