From bea13705ead78f11251944fa20e47cccad38680c Mon Sep 17 00:00:00 2001 From: Julien Viet Date: Thu, 14 Nov 2024 15:49:08 +0100 Subject: [PATCH] HTTP client load balancing example --- core-examples/README.adoc | 7 +++ .../core/http/loadbalancing/Client.java | 63 +++++++++++++++++++ .../core/http/loadbalancing/Servers.java | 15 +++++ .../example/core/http/simple/Server.java | 12 +++- grpc-examples/README.adoc | 6 +- .../Client.java | 4 +- .../Servers.java | 4 +- 7 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Client.java create mode 100644 core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Servers.java rename grpc-examples/src/main/java/io/vertx/example/grpc/{loadbalancer => loadbalancing}/Client.java (92%) rename grpc-examples/src/main/java/io/vertx/example/grpc/{loadbalancer => loadbalancing}/Servers.java (74%) diff --git a/core-examples/README.adoc b/core-examples/README.adoc index 7c240ed57..d1b709cfc 100644 --- a/core-examples/README.adoc +++ b/core-examples/README.adoc @@ -66,6 +66,13 @@ And a simple HTTP client which makes a request to the server. link:src/main/java/io/vertx/example/core/http/simple/Client.java[Java simple HTTP client] +=== Load balancing + +Demonstrate how to use client side load balancing + +link:src/main/java/io/vertx/example/core/http/loadbalancing/Servers.java[Start 3 HTTP servers on port 8080/8081/8082] +link:src/main/java/io/vertx/example/core/http/loadbalancing/Client.java[HTTP client load balancing example] + === HTTPS Like the simple example, but using HTTPS instead of HTTP diff --git a/core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Client.java b/core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Client.java new file mode 100644 index 000000000..1f864c45e --- /dev/null +++ b/core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Client.java @@ -0,0 +1,63 @@ +package io.vertx.example.core.http.loadbalancing; + +import io.vertx.core.Future; +import io.vertx.core.VerticleBase; +import io.vertx.core.http.HttpClient; +import io.vertx.core.http.RequestOptions; +import io.vertx.core.net.Address; +import io.vertx.core.net.AddressResolver; +import io.vertx.core.net.SocketAddress; +import io.vertx.core.net.endpoint.LoadBalancer; +import io.vertx.launcher.application.VertxApplication; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author Julien Viet + */ +public class Client extends VerticleBase { + + // This resolver simply response localhost:808x on a service.com:80 access + // we use such resolver here instead of DNS load balancing because there is no way to provide a local example + // with DNS load balancing that requires multiple network interfaces + private static final AddressResolver resolver = AddressResolver.mappingResolver(Collections + .>singletonMap(SocketAddress.inetSocketAddress(80, "service.com"), + Arrays.asList( + SocketAddress.inetSocketAddress(8080, "localhost"), + SocketAddress.inetSocketAddress(8081, "localhost"), + SocketAddress.inetSocketAddress(8082, "localhost")))::get); + + public static void main(String[] args) { + VertxApplication.main(new String[]{Client.class.getName()}); + } + + private HttpClient client; + + @Override + public Future start() throws Exception { + + // Load balancer of your choice + LoadBalancer loadBalancer = LoadBalancer.RANDOM; + + client = vertx.httpClientBuilder() + // In reality, we could avoid using such mock resolver and the client instead could use a server list provided by a DNS server + .withAddressResolver(resolver) + .withLoadBalancer(loadBalancer) + .build(); + + return client + .request(new RequestOptions().setServer(SocketAddress.inetSocketAddress(80, "service.com"))) + .compose(request -> { + System.out.println("Interacting with server " + request.connection().remoteAddress()); + return request + .send() + .compose(resp -> { + System.out.println("Got response " + resp.statusCode()); + return resp.body(); + }); + }) + .onSuccess(body -> System.out.println("Got data " + body.toString("ISO-8859-1"))); + } +} diff --git a/core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Servers.java b/core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Servers.java new file mode 100644 index 000000000..e8cd51379 --- /dev/null +++ b/core-examples/src/main/java/io/vertx/example/core/http/loadbalancing/Servers.java @@ -0,0 +1,15 @@ +package io.vertx.example.core.http.loadbalancing; + +import io.vertx.core.Vertx; +import io.vertx.example.core.http.simple.Server; + +public class Servers { + + public static void main(String[] args) { + Vertx vertx = Vertx.vertx(); + vertx.deployVerticle(new Server(8080)).await(); + vertx.deployVerticle(new Server(8081)).await(); + vertx.deployVerticle(new Server(8082)).await(); + System.out.println("Servers listening on ports 8080/8081/8082"); + } +} diff --git a/core-examples/src/main/java/io/vertx/example/core/http/simple/Server.java b/core-examples/src/main/java/io/vertx/example/core/http/simple/Server.java index 65eb8731d..72075267f 100644 --- a/core-examples/src/main/java/io/vertx/example/core/http/simple/Server.java +++ b/core-examples/src/main/java/io/vertx/example/core/http/simple/Server.java @@ -13,6 +13,16 @@ public static void main(String[] args) { VertxApplication.main(new String[]{Server.class.getName()}); } + private final int port; + + public Server(int port) { + this.port = port; + } + + public Server() { + this(8080); + } + @Override public Future start() throws Exception { return vertx @@ -20,6 +30,6 @@ public Future start() throws Exception { .requestHandler(req -> { req.response().putHeader("content-type", "text/html").end("

Hello from vert.x!

"); }) - .listen(8080); + .listen(port); } } diff --git a/grpc-examples/README.adoc b/grpc-examples/README.adoc index c8bb88583..7d6de0b94 100644 --- a/grpc-examples/README.adoc +++ b/grpc-examples/README.adoc @@ -111,12 +111,12 @@ link:src/main/java/io/vertx/example/grpc/jsonformat/ServerWithStub.java[gRPC ser link:src/main/java/io/vertx/example/grpc/jsonformat/Client.java[gRPC client example] link:src/main/java/io/vertx/example/grpc/jsonformat/ClientWithStub.java[gRPC client stub example] -== Load balancer +== Load balancing Demonstrate how to use client side load balancing -link:src/main/java/io/vertx/example/grpc/loadbalancer/Servers.java[Start 3 gRPC servers on port 8080/8081/8082] -link:src/main/java/io/vertx/example/grpc/loadbalancer/Client.java[gRPC load balancing example] +link:src/main/java/io/vertx/example/grpc/loadbalancing/Servers.java[Start 3 gRPC servers on port 8080/8081/8082] +link:src/main/java/io/vertx/example/grpc/loadbalancing/Client.java[gRPC client load balancing example] == SSL example diff --git a/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancer/Client.java b/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancing/Client.java similarity index 92% rename from grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancer/Client.java rename to grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancing/Client.java index 5316056b5..4599a766a 100644 --- a/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancer/Client.java +++ b/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancing/Client.java @@ -1,4 +1,4 @@ -package io.vertx.example.grpc.loadbalancer; +package io.vertx.example.grpc.loadbalancing; import io.grpc.examples.helloworld.HelloRequest; import io.grpc.examples.helloworld.VertxGreeterGrpcClient; @@ -45,7 +45,7 @@ public Future start() throws Exception { client = GrpcClient .builder(vertx) - // In reality we could avoid using such mock resolver and the client instead could use a server list provided by a DNS server + // In reality, we could avoid using such mock resolver and the client instead could use a server list provided by a DNS server .withAddressResolver(resolver) .withLoadBalancer(loadBalancer) .build(); diff --git a/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancer/Servers.java b/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancing/Servers.java similarity index 74% rename from grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancer/Servers.java rename to grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancing/Servers.java index 9457cc033..ae1256cfa 100644 --- a/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancer/Servers.java +++ b/grpc-examples/src/main/java/io/vertx/example/grpc/loadbalancing/Servers.java @@ -1,4 +1,4 @@ -package io.vertx.example.grpc.loadbalancer; +package io.vertx.example.grpc.loadbalancing; import io.vertx.core.Vertx; import io.vertx.example.grpc.helloworld.Server; @@ -10,6 +10,6 @@ public static void main(String[] args) { vertx.deployVerticle(new Server(8080)).await(); vertx.deployVerticle(new Server(8081)).await(); vertx.deployVerticle(new Server(8082)).await(); - System.out.println("Servers started on port 8080/8081/8082"); + System.out.println("Servers listening on ports 8080/8081/8082"); } }