3

Using Spring Cloud Gateway and Discovery Service for Seamless Request Routing

 9 months ago
source link: https://dzone.com/articles/using-spring-cloud-gateway-and-discovery-service-f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Using Spring Cloud Gateway and Discovery Service for Seamless Request Routing

In this tutorial, learn how to route requests between Java microservices with Spring Cloud Gateway and Discovery Service.

by

CORE ·

Aug. 04, 23 · Tutorial
Like (5)
6.91K Views

Spring Cloud is a versatile framework for building Java applications in various cloud environments. Today, we'll explore how to use two components of the framework - Spring Cloud Gateway and Discovery Service (aka Spring Cloud Netflix) - for easy routing of user requests between your Java microservices.

We'll build two microservices, register them with a Discovery Service instance, and use the Cloud Gateway for routing requests to a specific microservice instance. The cool thing is that the Cloud Gateway will also be registered with the Discovery Service and will use the latter to resolve a microservice name into an actual connection endpoint.

So, whether you prefer reading or watching, let’s walk through this practical example:

Creating Sample Microservices

Imagine we’re creating an online service for a pizza company. There are two basic capabilities the service needs to support - customers can order a pizza online and then track the order status. To achieve this, let's introduce two microservices - the Kitchen and the Tracker.

What's in store for Kubernetes in the Enterprise in 2023

Our 2022 Kubernetes report features insights into how teams leverage Kubernetes, K8s in AI, advancements in cluster observability, and more.

thumbnail?fid=16388824&w=350

Kitchen Microservice

The Kitchen microservice allows customers to place pizza orders. Once an order is placed, it'll hit the kitchen, and the chef will start cooking.

Let's create a basic implementation for the purpose of testing Spring Cloud Gateway with the Discovery Service. This service is a Spring Boot web application with a REST controller that simply acknowledges an order.

@RestController
@RequestMapping("/kitchen")
public class KitchenController {
  
    @PostMapping("/order")
    public ResponseEntity<String> addNewOrder(@RequestParam("id") int id) {
        return ResponseEntity.ok("The order has been placed!");
    }
}

The service will be listening on port 8081, which is set in the application.properties file:

Properties files
server.port=8081

Once the microservice is started you can use curl or HTTPie to test that the REST endpoint works. We’ll be using HTTPie throughout the article:

Shell
http POST localhost:8081/kitchen/order id==1

HTTP/1.1 200 
Connection: keep-alive
Content-Length: 26
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 18:45:26 GMT
Keep-Alive: timeout=60

The order has been placed!

Tracker Microservice

Customers use the second microservice, the Tracker, to check their order status.

We'll go the extra mile with this service implementation by supporting several order statuses, including ordered, baking, and delivering. Our mock implementation will randomly select one of these statuses:

@RestController
@RequestMapping("/tracker")
public class TrackerController {
    @GetMapping("/status")
    public ResponseEntity<String> getOrderStatus(@RequestParam("id") int orderId) {
        String[] status = { "Ordered", "Baking", "Delivering" };
        Random rand = new Random();

        return ResponseEntity.ok(status[rand.nextInt(status.length)]);
    }
}

The Tracker will be listening on port 8082, which is configured in the application.properties file:

Properties files
server.port=8082

Once the microservice is started, we can test it by sending the following GET request:

Shell
http GET localhost:8082/tracker/status id==1

HTTP/1.1 200 
Connection: keep-alive
Content-Length: 10
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 18:52:45 GMT
Keep-Alive: timeout=60

Delivering

Registering Microservices With Spring Cloud Discovery Service

Our next step is to register these two microservices with the Spring Cloud Discovery Service. But what exactly is a Discovery Service?

Discovery Service

The Discovery Service lets your microservices connect to each other using only their names. For instance, if Tracker needs to connect to Kitchen, the Discovery Service gives Tracker the IP addresses of Kitchen's available instances. This list can change - you can add or remove Kitchen instances as needed, and the Discovery Service always keeps the updated list of active endpoints.

There are several ways to start a Discovery Service server instance. One of the options is to use the Spring Initializr website to generate a Spring Boot project with the Eureka Server dependency.

Spring Initializr: Generate a project

If you choose that method, the generated project will come with the following class that initiates a server instance of the Discovery Service:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(DiscoveryServerApplication.class, args);
    }
}

By default, the server listens on port 8761. So, once we start the server, we can visit localhost:8761 to view the Discovery Service dashboard:

Spring Eureka: Service Discovery Dashboard

Currently, the Discovery Service is running, but no microservices are registered with it yet. Now, it's time to register our Kitchen and Tracker microservices.

Update the Kitchen Microservice

To register the Kitchen service with the Discovery Service, we need to make the following changes:

1. Add the Discovery Service’s client library to the Kitchen’s pom.xml file:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2. Annotate the Kitchen’s application class with @EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient
public class KitchenApplication {
    public static void main(String[] args) {
        SpringApplication.run(KitchenApplication.class, args);
    }
}

3. Update the application.properties file by adding these two parameters:

Properties files
# The microservice will be registered under this name 
# with the Discovery Service
spring.application.name=kitchen-service

# Discovery Service address
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

Update the Tracker Microservice

We need to follow the same steps to update the Tracker microservice. 

There's only one difference for Tracker: its name, which is provided via the spring.application.name property in the application.properties file:

Properties files
# The microservice will be registered under this name with the Discovery Service
spring.application.name=tracker-service

Register Microservices

Finally, restart the microservices to confirm their registration with the Discovery Service.

Restart the microservices to confirm their registration with the Discovery Service

As expected, both the Kitchen and Tracker microservices successfully register with the Discovery Service! Now, it's time to focus on the Spring Cloud Gateway.

Spring Cloud Gateway

Spring Cloud Gateway is used to resolve user requests and forward them to the appropriate microservices or API endpoints for further processing.

You can generate a Spring Boot project with Cloud Gateway support using the same Spring Initializr website. Simply add the Gateway and Eureka Discovery Client libraries, then click the generate button:

Add the Gateway and Eureka Discovery Client libraries, then click the generate button

The Gateway will serve as a one-stop solution for directing requests to Kitchen and Tracker instances. Its implementation is simple yet powerful:

@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
        	.route("kitchen-route", r -> r.path("/kitchen/**").uri("lb://kitchen-service"))
         	.route("tracker-route", r -> r.path("/tracker/**").uri("lb://tracker-service"))
         	.build();
    }
}

The Gateway supports two routes:

  1. The kitchen-route is for all requests beginning with the /kitchen/** path.
  2. The tracker-route is for requests starting with the /tracker/** path.

The most interesting part of this route configuration is how we define the destination endpoint (the uri(...) part of the configuration). Each destination starts with lb:, followed by a microservice name. When the Gateway encounters such a destination URL, it will use the Discovery Service to resolve a microservice name into an IP address of a microservice instance and establish a connection to it. Furthermore, lb stands for load balancer, which means the Gateway will distribute requests evenly if the Discovery Service returns several instances of the same microservice.

Finally, once we initiate the Gateway, it begins to monitor port 8080 for incoming traffic. We can then use the following HTTP requests to confirm that the Gateway is successfully routing our requests to the Kitchen and Tracker microservices!

Shell
http POST localhost:8080/kitchen/order id==2

HTTP/1.1 200 OK
Content-Length: 26
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 20:11:26 GMT

The order has been placed!


http GET localhost:8080/tracker/status id==2

HTTP/1.1 200 OK
Content-Length: 6
Content-Type: text/plain;charset=UTF-8
Date: Thu, 03 Aug 2023 20:11:41 GMT

Baking

Summary

With Spring Cloud, building robust, scalable Java applications for the cloud has never been easier. Say goodbye to the hassles of tracking IP addresses and instances, and say hello to intelligent, effortless request routing. Enjoy!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK