- import the dependency
<dependency>
<groupId>io.github.pangzixiang.whatsit</groupId>
<artifactId>vertx-router</artifactId>
<version>{latestVersion}</version>
</dependency>
- deploy the Verticle 'VertxRouterVerticle'
public class Main {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
SelfSignedCertificate selfSignedCertificate = SelfSignedCertificate.create();
HttpServerOptions sslOptions = new HttpServerOptions().setSsl(true).setKeyCertOptions(selfSignedCertificate.keyCertOptions()).setTrustOptions(selfSignedCertificate.trustOptions());
VertxRouterVerticleOptions vertxRouterVerticleOptions = new VertxRouterVerticleOptions()
.setProxyServerPort(8080)
.setListenerServerPort(9090)
.setProxyServerInstanceNumber(4)
.setListenerServerOptions(sslOptions)
.setProxyServerOptions(sslOptions)
.setListenerServerInstanceNumber(4)
.setProxyHttpClientOptions(new HttpClientOptions().setSsl(true).setTrustAll(true))
.setEnableBasicAuthentication(true)
.setLoadBalanceAlgorithm(new LeastConnection())
.setBasicAuthenticationUsername("vertx-router")
.setBasicAuthenticationPassword("vertx-router-pwd");
vertx.deployVerticle(new VertxRouterVerticle(vertxRouterVerticleOptions));
}
}
- you can also set your preferred load balance algorithm
public class Main {
public static void main(String[] args) {
vertx.deployVerticle(new VertxRouterVerticle(VertxRouterVerticleOptions.builder()
.loadBalanceAlgorithm(new LeastConnection())
.build()));
}
}
By default, the load balance algorithm is Round Robin and this library provides below 3 kinds of Algorithm:
- LeastConnection.class
- RandomAlgorithm.class
- RoundRobin.class
- IpHash.class
- you can also design your own load balance algorithm by implementing LoadBalanceAlgorithm.class
import io.github.pangzixiang.whatsit.vertx.router.algorithm.LoadBalanceAlgorithm;
public class YourAlgorithm implements LoadBalanceAlgorithm {
@Override
public Future<SocketAddress> handle(Vertx vertx, HttpServerRequest httpServerRequest, Map<String, SocketAddress> socketAddressMap) {
// try sth
return Future.succeededFuture(socketAddressMap.values().stream().toList().get(0));
}
}
- Target Services use Websocket to register themselves
public class Main {
public static void main(String[] args) {
Router router1 = Router.router(vertx);
router1.route().handler(BodyHandler.create());
router1.route().handler(routingContext -> {
log.info("target service 1 received request from {}", routingContext.normalizedPath());
routingContext.next();
});
router1.route("/test-service/test").handler(routingContext -> {
routingContext.response().end("done");
});
router1.route(HttpMethod.POST, "/test-service/test1").handler(routingContext -> {
routingContext.response().end(routingContext.body().asString());
});
Future<HttpServer> httpServerFuture1 = vertx.createHttpServer(sslOptions)
.requestHandler(router1)
.listen(0);
Router router2 = Router.router(vertx);
router2.route().handler(BodyHandler.create());
router2.route().handler(routingContext -> {
log.info("target service 2 received request from {}", routingContext.normalizedPath());
routingContext.next();
});
router2.route(HttpMethod.POST, "/test-service/test1").handler(routingContext -> {
routingContext.response().end(routingContext.body().asString());
});
Future<HttpServer> httpServerFuture2 = vertx.createHttpServer(sslOptions)
.requestHandler(router2)
.listen(0);
Future.all(httpServerFuture1, httpServerFuture2)
.onSuccess(unused1 -> {
log.info("Target service started at {}", httpServerFuture1.result().actualPort());
HttpClientOptions options = new HttpClientOptions();
options.setSsl(true);
options.setTrustAll(true);
HttpClient httpClient1 = vertx.createHttpClient(options);
WebSocketConnectOptions webSocketConnectOptions1 = new WebSocketConnectOptions();
webSocketConnectOptions1.setHost("localhost");
webSocketConnectOptions1.setPort(9090);
webSocketConnectOptions1.setSsl(true);
webSocketConnectOptions1.setURI("/register");
MultiMap headers1 = MultiMap.caseInsensitiveMultiMap();
headers1.add("host", "localhost");
headers1.add("port", String.valueOf(httpServerFuture1.result().actualPort()));
headers1.add("name", "test-service");
headers1.add("Authorization", "Basic dmVydHgtcm91dGVyOnZlcnR4LXJvdXRlci1wd2Q=");
webSocketConnectOptions1.setHeaders(headers1);
httpClient1.webSocket(webSocketConnectOptions1).onSuccess(unused2 -> {
log.info("Target Service1 connected to Proxy service");
vertx.setTimer(10000, l -> httpClient1.close());
}).onFailure(throwable -> {
log.error("Target Service1 failed to connect to Proxy Service", throwable);
});
HttpClient httpClient2 = vertx.createHttpClient(options);
WebSocketConnectOptions webSocketConnectOptions2 = new WebSocketConnectOptions();
webSocketConnectOptions2.setHost("localhost");
webSocketConnectOptions2.setPort(9090);
webSocketConnectOptions2.setSsl(true);
webSocketConnectOptions2.setURI("/register");
MultiMap headers2 = MultiMap.caseInsensitiveMultiMap();
headers2.add("host", "localhost");
headers2.add("port", String.valueOf(httpServerFuture2.result().actualPort()));
headers2.add("name", "test-service");
headers2.add("Authorization", "Basic dmVydHgtcm91dGVyOnZlcnR4LXJvdXRlci1wd2Q=");
webSocketConnectOptions2.setHeaders(headers2);
httpClient2.webSocket(webSocketConnectOptions2).onSuccess(unused2 -> {
log.info("Target Service2 connected to Proxy service");
vertx.setTimer(15000, l -> httpClient2.close());
}).onFailure(throwable -> {
log.error("Target Service2 failed to connect to Proxy Service", throwable);
});
});
}
}
- Target Services can also use vertx-router-connector to connect
<dependency>
<groupId>io.github.pangzixiang.whatsit</groupId>
<artifactId>vertx-router-connector</artifactId>
<version>{version}</version>
</dependency>
public class Main {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
Router router = Router.router(vertx);
String serviceName = "test-service";
router.route("/" + serviceName + "/test").handler(routingContext -> {
routingContext.response().end("test");
});
vertx.createHttpServer()
.requestHandler(router)
.listen(0)
.onSuccess(httpServer -> {
VertxRouterConnectorVerticleOptions options = VertxRouterConnectorVerticleOptions
.builder()
.routerHost("localhost")
.routerPort(9090)
.registerURI("/register")
.serviceHost("localhost")
.servicePort(httpServer.actualPort())
.serviceName(serviceName)
.optionalHeaders(MultiMap.caseInsensitiveMultiMap().add("Authorization", "Basic dmVydHgtcm91dGVyOnZlcnR4LXJvdXRlci1wd2Q="))
.build();
vertx.deployVerticle(new VertxRouterConnectorVerticle(options)).onSuccess(id -> {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
vertx.undeploy(id);
}));
});
})
.onFailure(throwable -> {
log.error("Failed to start up http server", throwable);
});
}
}