This guide walks you through the process of creating load-balanced microservices.
What you’ll build
You’ll build a microservice application that uses Spring Cloud LoadBalancer to provide client-side load-balancing in calls to another microservice.
What you’ll need
Implement "Say Hello" service
Our "server" service is called "Say Hello".
It will return a random greeting (picked out of a static list of three) from an endpoint accessible at
src/main/java/hello, create the file
SayHelloApplication.java. It should look like this:
It’s a simple
@RestController, where we have one
@RequestMapping method for
/greeting and then another for the root path
We’re going to run multiple instances of this application locally alongside a client service application, so create the directory
src/main/resources, create the file
application.yml within it, and then, in that file, set a default value for server.port.
(We’ll instruct the other instances of the application to run on other ports, as well, so that none of the
Say Hello instances will conflict with the client when we get that running).
While we’re in this file, we’ll set the
spring.application.name for our service too.
Access from a client service
The "User" application will be what our user sees.
It will make a call to the Say Hello application to get a greeting and then send that to our user when the user visits the endpoints at
In the User application directory, under
src/main/java/hello, add the file
We also add a
@Configuration class where we will set up a load-balanced
The configuration provides a
@LoadBalanced WebClient.Builder instance, that we use when someone hits the
hi endpoint of
hi endpoint is hit, we will use this builder to create a
WebClient instance which will be used to make an HTTP
GET request to the Say Hello service’s URL and give us the result as a
UserApplication.java, we have also added a
/hello endpoint that does the same action underneath, however, rather than using the
@LoadBalanced annotation, we make use of an
@Autowired load-balancer exchange filter function
lbFunction that we pass using the
filter() method to a
WebClient instance that we are building programmatically.
Even though we set up the load-balanced
server.port properties to
Load-balance across server instances
Now we can access
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!
As you will see, in
WebClientConfig.java, we pass a custom configuration for the LoadBalancer using the
@LoadBalancerClient(name = "say-hello", configuration = SayHelloConfiguration.class).
This means that whenever a service named
say-hello is being contacted, instead of running with the default setup, Spring Cloud LoadBalancer will use the configuration provided in
There, we provide a custom
ServiceInstanceListSupplier with 3 hard-coded instances that Spring Cloud LoadBalancer will choose from while making the calls to the "Say Hello" service.
This step has been added to explain how you can pass your own custom configuration to the Spring Cloud LoadBalancer.
However, you don’t need to use the
We also add an
application.yml file with default
Trying it out
Run the Say Hello service, using either Gradle:
$ ./gradlew bootRun
$ mvn spring-boot:run
Run other instances on ports 9092 and 9999, again using either Gradle:
$ SERVER_PORT=9092 ./gradlew bootRun
$ SERVER_PORT=9999 mvn spring-boot:run
Then start up the User service.
localhost:8888/hi and then watch the Say Hello service instances.
And your requests to the User service should result in calls to Say Hello being spread across the running instances in round-robin form:
2016-03-09 21:15:28.915 INFO 90046 --- [nio-8090-exec-7] hello.SayHelloApplication : Access /greeting
Test the application
Now that the application is running, you can test it.
Congratulations! You’ve just developed a Spring application!