Giter VIP home page Giter VIP logo

izeye / gs-spring-cloud-loadbalancer Goto Github PK

View Code? Open in Web Editor NEW

This project forked from spring-guides/gs-spring-cloud-loadbalancer

0.0 1.0 0.0 354 KB

Client-Side Load-Balancing with Spring Cloud LoadBalancer :: Dynamically select correct instance for the request :: spring-cloud,spring-cloud-loadbalancer,spring-cloud-commons

Home Page: https://spring.io/guides/gs/spring-cloud-loadbalancer/

License: Apache License 2.0

Shell 3.77% Java 96.23%

gs-spring-cloud-loadbalancer's Introduction

This guide walks you through the process of creating load-balanced microservices.

What You Will Build

You will build a microservice application that uses Spring Cloud LoadBalancer to provide client-side load-balancing in calls to another microservice.

What You Will Need

  • About 15 minutes

  • A favorite text editor or IDE

  • JDK 1.8 or later

  • Gradle 6+ or Maven 3.5+

  • You can also import the code straight into your IDE:

  • Spring Tool Suite (STS) or IntelliJ IDEA

Create a Root Project

This guide walks through building two projects, one of which is a dependency to the other. Consequently, you need to create two child projects under a root project. First, create the build configuration at the top level. For Maven, you need a pom.xml with <modules> that list the subdirectories:

link:complete/pom.xml[role=include]

For Gradle, you need want a settings.gradle that includes the same directories:

link:complete/settings.gradle[role=include]

Optionally, you can include an empty build.gradle (to help IDEs identify the root directory).

Create the Directory Structure

In the directory that you want to be your root directory, create the following subdirectory structure (for example, with mkdir say-hello user on *nix systems):

└── say-hello
└── user

In the root of the project, you need to set up a build system, and this guide shows you how to use Maven or Gradle.

Starting with Spring Initializr

If you use Maven for the Say Hello project, visit the Spring Initializr to generate a new project with the required dependency (Spring Web).

The following listing shows the pom.xml file that is created when you choose Maven:

link:initial/say-hello/pom.xml[role=include]

If you use Gradle for the Say Hello project, visit the Spring Initializr to generate a new project with the required dependency (Spring Web).

The following listing shows the build.gradle file that is created when you choose Gradle:

link:initial/say-hello/build.gradle[role=include]

If you use Maven for the User project, visit the Spring Initializr to generate a new project with the required dependencies (Cloud Loadbalancer and Spring Reactive Web).

The following listing shows the pom.xml file that is created when you choose Maven:

link:initial/user/pom.xml[role=include]

If you use Gradle for the User project, visit the Spring Initializr to generate a new project with the required dependencies (Cloud Loadbalancer and Spring Reactive Web).

The following listing shows the build.gradle file that is created when you choose Gradle:

link:initial/user/build.gradle[role=include]

Manual Initialization (optional)

If you want to initialize the project manually rather than use the links shown earlier, follow the steps given below:

  1. Navigate to https://start.spring.io. This service pulls in all the dependencies you need for an application and does most of the setup for you.

  2. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.

  3. Click Dependencies and select Spring Web (for the Say Hello project) or Cloud Loadbalancer and Spring Reactive Web (for the User project).

  4. Click Generate.

  5. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.

Note
If your IDE has the Spring Initializr integration, you can complete this process from your IDE.

Implement the "Say Hello" service

Our “server” service is called Say Hello. It returns a random greeting (picked out of a static list of three) from an endpoint that is accessible at /greeting.

In src/main/java/hello, create the file SayHelloApplication.java.

The following listing shows the contents of say-hello/src/main/java/hello/SayHelloApplication.java:

link:complete/say-hello/src/main/java/hello/SayHelloApplication.java[role=include]

It is a simple @RestController, where we have one @RequestMapping method for the /greeting and another for the root path /.

We are going to run multiple instances of this application locally alongside a client service application. To get started:

  1. Create a src/main/resources directory.

  2. Create a application.yml file within the directory.

  3. In that file, set a default value for server.port.

(We will instruct the other instances of the application to run on other ports so that none of the Say Hello instances conflict with the client when we get that running). While we are in this file, we can set the spring.application.name for our service too.

The following listing shows the contents of say-hello/src/main/resources/application.yml:

link:complete/say-hello/src/main/resources/application.yml[role=include]

Access from a Client Service

Our users see the User application. It makes a call to the Say Hello application to get a greeting and then sends that greeting to our user when the user visits the endpoints at /hi and /hello.

In the User application directory, under src/main/java/hello, add the UserApplication.java file:

The following listing shows the contents of user/src/main/java/hello/UserApplication.java

link:complete/user/src/main/java/hello/UserApplication.java[role=include]

We also need a @Configuration class where we set up a load-balanced WebClient.Builder instance:

The following listing shows the contents of user/src/main/java/hello/WebClientConfig.java:

link:complete/user/src/main/java/hello/WebClientConfig.java[role=include]

The configuration provides a @LoadBalanced WebClient.Builder instance, which we use when someone hits the hi endpoint of UserApplication.java. Once the hi endpoint is hit, we use this builder to create a WebClient instance, which makes an HTTP GET request to the Say Hello service’s URL and gives us the result as a String.

In UserApplication.java, we have also added a /hello endpoint that does the same action. However, rather than use the @LoadBalanced annotation, we use an @Autowired load-balancer exchange filter function (lbFunction), which we pass by using the filter() method to a WebClient instance that we programmatically build.

Tip
Even though we set up the load-balanced WebClient instance slightly differently for the two endpoints, the end behavior for both is exactly the same. Spring Cloud LoadBalancer is used to select an appropriate instance of the Say Hello service.

Add the spring.application.name and server.port properties to src/main/resources/application.properties or src/main/resources/application.yml:

The following listing shows the contents of user/src/main/resources/application.yml

link:complete/user/src/main/resources/application.yml[role=include]

Loadbalance Across Server Instances

Now we can access /hi or hello on the User service and see a friendly greeting:

$ curl http://localhost:8888/hi
Greetings, Mary!

$ curl http://localhost:8888/hi?name=Orontes
Salutations, Orontes!

In WebClientConfig.java, we pass a custom configuration for the LoadBalancer by using the @LoadBalancerClient annotation:

@LoadBalancerClient(name = "say-hello", configuration = SayHelloConfiguration.class)

This means that, whenever a service named say-hello is contacted, instead of running with the default setup, Spring Cloud LoadBalancer uses the configuration provided in SayHelloConfiguration.java.

The following listing shows the contents of user/src/main/java/hello/SayHelloConfiguration.java:

link:complete/user/src/main/java/hello/SayHelloConfiguration.java[role=include]

In that class, we provide a custom ServiceInstanceListSupplier with three hard-coded instances that Spring Cloud LoadBalancer chooses from while making the calls to the Say Hello service.

Note
This step has been added to explain how you can pass your own custom configuration to the Spring Cloud LoadBalancer. However, you need not use the @LoadBalancerClient annotation and create your own configuration for the LoadBalancer. The most typical way is to use Spring Cloud LoadBalancer with service discovery. If you have any DiscoveryClient on your classpath, the default Spring Cloud LoadBalancer configuration uses it to check for service instances. As a result, you only choose from instances that are up and running. You can learn how to use ServiceDiscovery with this guide.

We also add an application.yml file with default server.port and spring.application.name.

The following listing shows the contents of user/src/main/resources/application.yml:

link:complete/user/src/main/resources/application.yml[role=include]

Testing the Loadbalancer

The following listing shows how to run the Say Hello service with Gradle:

$ ./gradlew bootRun

The following listing shows how to run the Say Hello service with Maven:

$ mvn spring-boot:run

You can run other instances on ports 9092 and 9999 To do so with Gradle, run the following command:

$ SERVER_PORT=9092 ./gradlew bootRun

To do so with Maven, run the following command:

$ SERVER_PORT=9999 mvn spring-boot:run

Then you can start the User service. To do so, access localhost:8888/hi and watch the Say Hello service instances.

Your requests to the User service should result in calls to Say Hello being spread across the running instances in round-robin fashion:

2016-03-09 21:15:28.915  INFO 90046 --- [nio-8090-exec-7] hello.SayHelloApplication                : Access /greeting

Summary

Congratulations! You have just developed a Spring Loadbalancer application!

gs-spring-cloud-loadbalancer's People

Contributors

olgamaciaszek avatar gregturn avatar a-mroz avatar buzzardo avatar ugir avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.