-
Notifications
You must be signed in to change notification settings - Fork 140
Wiring in Vertx and QBit to work together with health and stats
I am basing this on the first example to mix/match QBit and Vert.x.
QBit health system and stats is part of the ManagedServiceBuilder.
The ManagedServiceBuilder
will automatically wire in health and stats, but it also wires in the end points.
We have to map the end point services exposed in QBit
to Vertx
and we do that with a route.
/* Route everything under /hello to QBit http server. */
final Route qbitRoute = router.route().path("/hello/*");
/* Vertx HTTP Server. */
final io.vertx.core.http.HttpServer vertxHttpServer =
this.getVertx().createHttpServer();
/*
* Use the VertxHttpServerBuilder which is a special builder for Vertx/Qbit integration.
*/
final HttpServer httpServer = VertxHttpServerBuilder.vertxHttpServerBuilder()
.setRoute(qbitRoute)
.setHttpServer(vertxHttpServer)
.setVertx(getVertx())
.build();
We then pass that route to our integration lib VertxHttpServerBuilder.
But as you know. This will only route built in services and health and metrics are not part of the normal service end point flow (perhaps they should have been).
First lets get the EndpointBuilder which manages wiring in the health and stats systems.
final EndpointServerBuilder endpointServerBuilder = managedServiceBuilder
.getEndpointServerBuilder().setUri("/")
.addService(new HelloWorldService())
.setHttpServer(httpServer);
To map in the health end point and the metrics end point (there are many ways), you could use additional routes from vertx as follows:
/* Route everything under /__health to QBit health system. */
final Route healthRoute = router.route().path("/__health");
final HealthServiceAsync healthService = endpointServerBuilder.getHealthService();
healthRoute.handler(event -> healthService.ok(aBoolean -> event.response().end(aBoolean.toString())));
It is actually fairly simple. Three lines of code.
To map in built-in metrics you would do this:
/* Route everything under /__stats/instance to QBit stats system. */
final Route statsRoute = router.route().path("/__stats/instance");
final Route globalStats = router.route().path("/__stats");
final StatCollection statsCollection = endpointServerBuilder.getStatsCollection();
statsRoute.handler(event -> statsCollection.collect(stats -> {
String json = JsonFactory.toJson(stats);
event.response().end(json);
}));
globalStats.handler(event -> {
event.response().end("{\"version\":1}");
});
Here is the full example:
package io.advantageous.qbit.example.vertx;
import io.advantageous.boon.json.JsonFactory;
import io.advantageous.qbit.admin.ManagedServiceBuilder;
import io.advantageous.qbit.http.server.HttpServer;
import io.advantageous.qbit.server.EndpointServerBuilder;
import io.advantageous.qbit.server.ServiceEndpointServer;
import io.advantageous.qbit.service.health.HealthServiceAsync;
import io.advantageous.qbit.service.stats.StatCollection;
import io.advantageous.qbit.system.QBitSystemManager;
import io.advantageous.qbit.vertx.http.VertxHttpServerBuilder;
import io.vertx.core.*;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
public class HelloWorldVerticle extends AbstractVerticle {
private final int port;
private QBitSystemManager systemManager;
public HelloWorldVerticle(int port) {
this.port = port;
}
public static void main(final String... args) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final HelloWorldVerticle helloWorldVerticle = new HelloWorldVerticle(8080);
final AtomicReference<AsyncResult> asyncResultRef = new AtomicReference<>();
Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(5));
vertx.deployVerticle(helloWorldVerticle, result -> {
if (result.succeeded()) {
System.out.println("Deployment id is: " + result.result());
asyncResultRef.set(result);
} else {
System.out.println("Deployment failed!");
result.cause().printStackTrace();
}
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
if (asyncResultRef.get().succeeded()) {
System.out.println("Server started");
}
}
public void start() {
try {
/* Route one call to a vertx handler. */
final Router router = Router.router(vertx); //Vertx router
router.route("/svr/rout1/").handler(routingContext -> {
HttpServerResponse response = routingContext.response();
response.setStatusCode(202);
response.end("route1");
});
/* Route everything under /hello to QBit http server. */
final Route qbitRoute = router.route().path("/hello/*");
/* Vertx HTTP Server. */
final io.vertx.core.http.HttpServer vertxHttpServer =
this.getVertx().createHttpServer();
/*
* Use the VertxHttpServerBuilder which is a special builder for Vertx/Qbit integration.
*/
final HttpServer httpServer = VertxHttpServerBuilder.vertxHttpServerBuilder()
.setRoute(qbitRoute)
.setHttpServer(vertxHttpServer)
.setVertx(getVertx())
.build();
/** Use a managed service builder. */
final ManagedServiceBuilder managedServiceBuilder = ManagedServiceBuilder.managedServiceBuilder();
final EndpointServerBuilder endpointServerBuilder = managedServiceBuilder
.getEndpointServerBuilder().setUri("/")
.addService(new HelloWorldService())
.setHttpServer(httpServer);
/* Route everything under /__health to QBit health system. */
final Route healthRoute = router.route().path("/__health");
final HealthServiceAsync healthService = endpointServerBuilder.getHealthService();
healthRoute.handler(event -> healthService.ok(aBoolean -> event.response().end(aBoolean.toString())));
/* Route everything under /__stats/instance to QBit stats system. */
final Route statsRoute = router.route().path("/__stats/instance");
final Route globalStats = router.route().path("/__stats");
final StatCollection statsCollection = endpointServerBuilder.getStatsCollection();
statsRoute.handler(event -> statsCollection.collect(stats -> {
String json = JsonFactory.toJson(stats);
event.response().end(json);
}));
globalStats.handler(event -> {
event.response().end("{\"version\":1}");
});
/*
* Create a new service endpointServer.
*/
final ServiceEndpointServer endpointServer = endpointServerBuilder.build();
endpointServer.startServer();
systemManager = managedServiceBuilder.getSystemManager();
/*
* Associate the router as a request handler for the vertxHttpServer.
*/
vertxHttpServer.requestHandler(router::accept).listen(port);
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
public void stop() {
if (systemManager != null) {
systemManager.shutDown();
}
}
}
package io.advantageous.qbit.example.vertx;
import io.advantageous.qbit.annotation.RequestMapping;
import io.advantageous.qbit.annotation.RequestMethod;
@RequestMapping("/hello")
public class HelloWorldService {
@RequestMapping(value = "/world", method = RequestMethod.POST)
public String hello(String body) {
return "hello " + body;
}
@RequestMapping(value = "/hi/", method = RequestMethod.GET)
public String hi() {
return "hi ";
}
}
$ curl http://localhost:8080/__stats/instance
{"MetricsKV":{"HelloWorldService":1},"MetricsMS":{},"MetricsC":{"HelloWorldService.startBatchCount":5,"HelloWorldService.receiveCount":5},"version":1}
$ curl http://localhost:8080/__stats
{"version":1}
$ curl http://localhost:8080/__health
true
QBit Website What is Microservices Architecture?
QBit Java Micorservices lib tutorials
The Java microservice lib. QBit is a reactive programming lib for building microservices - JSON, HTTP, WebSocket, and REST. QBit uses reactive programming to build elastic REST, and WebSockets based cloud friendly, web services. SOA evolved for mobile and cloud. ServiceDiscovery, Health, reactive StatService, events, Java idiomatic reactive programming for Microservices.
Reactive Programming, Java Microservices, Rick Hightower
Java Microservices Architecture
[Microservice Service Discovery with Consul] (http://www.mammatustech.com/Microservice-Service-Discovery-with-Consul)
Microservices Service Discovery Tutorial with Consul
[Reactive Microservices] (http://www.mammatustech.com/reactive-microservices)
[High Speed Microservices] (http://www.mammatustech.com/high-speed-microservices)
Reactive Microservices Tutorial, using the Reactor
QBit is mentioned in the Restlet blog
All code is written using JetBrains Idea - the best IDE ever!
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting
Tutorials
- QBit tutorials
- Microservices Intro
- Microservice KPI Monitoring
- Microservice Batteries Included
- RESTful APIs
- QBit and Reakt Promises
- Resourceful REST
- Microservices Reactor
- Working with JSON maps and lists
__
Docs
Getting Started
- First REST Microservice
- REST Microservice Part 2
- ServiceQueue
- ServiceBundle
- ServiceEndpointServer
- REST with URI Params
- Simple Single Page App
Basics
- What is QBit?
- Detailed Overview of QBit
- High level overview
- Low-level HTTP and WebSocket
- Low level WebSocket
- HttpClient
- HTTP Request filter
- HTTP Proxy
- Queues and flushing
- Local Proxies
- ServiceQueue remote and local
- ManagedServiceBuilder, consul, StatsD, Swagger support
- Working with Service Pools
- Callback Builders
- Error Handling
- Health System
- Stats System
- Reactor callback coordination
- Early Service Examples
Concepts
REST
Callbacks and Reactor
Event Bus
Advanced
Integration
- Using QBit in Vert.x
- Reactor-Integrating with Cassandra
- Using QBit with Spring Boot
- SolrJ and service pools
- Swagger support
- MDC Support
- Reactive Streams
- Mesos, Docker, Heroku
- DNS SRV
QBit case studies
QBit 2 Roadmap
-- Related Projects
- QBit Reactive Microservices
- Reakt Reactive Java
- Reakt Guava Bridge
- QBit Extensions
- Reactive Microservices
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting