Rick

Rick
Rick

Tuesday, September 22, 2015

QBit and Vertx3 : Best of both worlds for Microservices

QBit support Vertx 3. This allows you to create a service which can also serve up web pages and web resources for an app (an SPA). Prior to this, QBit has been more focused on just being a REST microservices, i.e., routing HTTP calls and WebSocket messages to Java methods. Rather then reinvent the world. QBit now supports Vertx 3.
The QBit support for Vertx 3 exceeds the support for Vertx 2.
QBit allows REST style support via annotations.

Example of QBit REST style support via annotations.

    @RequestMapping(value = "/todo", method = RequestMethod.DELETE)
    public void remove(final Callback<Boolean> callback, 
                       final @RequestParam("id") String id) {

        Todo remove = todoMap.remove(id);
        callback.accept(remove!=null);

    }
QBit, microservices lib, also provides integration with Consul, a typed event bus (which can be clustered), and really simplifies complex reactive async callback coordination between services, and a lot more. Please read through the QBit overview.
History: QBit at first only ran inside of Vertx2 . Then we decided to (client driven decision)  make it stand alone and we lost the ability to run it embedded inside of Vertx (we did not need it for any project on the road map). QBit was heavily inspired by Vertx and Akka.
Now you can use QBit features and Vertx 3 features via a mix and match model. You do this by setting up routers and/or a route in Vertx 3 to route to an HttpServer in QBit, and this takes about 1 line of code.
This means we can use Vertx 3's chunking, streaming, routing, etc. for complex HTTP support, HTTP auth, its Shiro Integration, etc. As well as use Vertx 3 as a normal HttpServer to serve up resources, but when we want to use REST style, async callbacks we can use QBit for routing REST calls to Java methods (as well as routing WebSocket messages to Java methods). We can access all of the features of Vertx 3. 
(Recall: QBit was originally written as a Vertx 2 add-on lib, but then we had clients that wanted to run in standalone and clients who wanted to use it with Servlets / Embedded Jetty. This is more coming back home versus a new thing. We also had pressure to add systems for microservices like monitoring, service discovery, health checks, etc. We did this at the same time Vertx 3 was adding similar features to support microservices.).
You can run QBit standalone and if you do, it uses Vertx 3 like a network lib, or you can run QBit inside of Vertx 3.
We moved this up the priority wish list for QBit for two reasons. We were going to start using Vertx support for DNS to read DNS entries for service discovery in a Heroku like environment. It made no sense to invest a lot of time using Vertx 2 API when we were switching to Vertx 3 in the short time. We also had some services that needed to deliver up an SPA (Single Page App), so we had to extend the support for Vertx anyway or add these features to QBit (which it sort of has but not really its focus so we would rather just delegate that to Vertx 3), and it made no sense to do that with Vertx 2.
Also the Vertx 3 environment and community is a very vibrant one with many shared philosophies to QBit. Let's cover where the Vertx3 integration and QBit come in.

Vertx 3 Integration and QBit, microservices lib integration, details. 
We added a new class called a VertxHttpServerBuilder (extends HttpServerBuilder), which allows one to build a QBit HTTP server from a vertx object, a vertxHttpServer and optionally from a Vertx router or a Vertx route.
Note that you can pass QBit HttpServerBuilder or a QBit HttpServer to a QBitEndpointServerBuilder to use that builder instead or HttpServer instead of the default.VertxHttpServerBuilder is a QBit HttpServerBuilder so you construct it, associate it with vertx, and then inject it into EndpointServerBuilder. This is how we integrate with the QBit REST/WebSocket support. If you are using QBit REST with Vertx, that is one integration point.
Also note that you can pass HttpServerBuilder or a HttpServer to aManagedServiceBuilder to use that builder instead or HttpServer instead of the default. If you wanted to use QBit REST and QBit Swagger support with Vertx then you would want to use ManagedServiceBuilder with this class.
Here are some docs taken from our JavaDocs for QBit VertxHttpServerBuilder.VertxHttpServerBuilder also allows one to pass a shared Vertx object if running inside of the Vertx world. It also allows one to pass a shared vertx HttpServer if you want to use more than just QBit routing. If you are using Vertx routing or you want to limit this QBit HttpServer to one route then you can pass a route.
Note: QBits Vertx 2 support is EOL. We will be phasing it out shortly.
Here are some code examples on how to mix and match QBit and Vertx3.

Usage

Creating a QBit HttpServer that is tied to a single vertx route

    HttpServer httpServer = VertxHttpServerBuilder.vertxHttpServerBuilder()
                    .setVertx(vertx).setHttpServer(httpServer).setRoute(route).build();
    httpServer.start();

Creating a QBit HttpServer server and passing a router so it can register itself as the default route

    Router router = Router.router(vertx); //Vertx router
    Route route1 = router.route("/some/path/").handler(routingContext -> {
    HttpServerResponse response = routingContext.response();
         // enable chunked responses because we will be adding data as
         // we execute over other handlers. This is only required once and
         // only if several handlers do output.
         response.setChunked(true);
         response.write("route1\n");

         // Call the next matching route after a 5 second delay
        routingContext.vertx().setTimer(5000, tid -> routingContext.next());
    });

    //Now install our QBit Server to handle REST calls.
    vertxHttpServerBuilder = VertxHttpServerBuilder.vertxHttpServerBuilder()
                    .setVertx(vertx).setHttpServer(httpServer).setRouter(router);

    HttpServer httpServer = vertxHttpServerBuilder.build();
    httpServer.start();
Note that you can pass HttpServerBuilder or a HttpServer toEndpointServerBuilder to use that builder instead or HttpServer instead of the default. If you are using QBit REST with Vertx, that is one integration point.

EndpointServerBuilder integration

    //Like before
    vertxHttpServerBuilder = VertxHttpServerBuilder.vertxHttpServerBuilder()
                    .setVertx(vertx).setHttpServer(httpServer).setRouter(router);

    //Now just inject it into the vertxHttpServerBuilder before you call build
    HttpServer httpServer = vertxHttpServerBuilder.build();
    endpointServerBuilder.setHttpServer(httpServer);
Also note that you can pass HttpServerBuilder or a HttpServer to aManagedServiceBuilder to use that builder instead or HttpServer instead of the default.
If you wanted to use QBit REST and QBit Swagger support with Vertx then you would want to use ManagedServiceBuilder with this class.

ManagedServiceBuilder integration

    //Like before
    vertxHttpServerBuilder = VertxHttpServerBuilder.vertxHttpServerBuilder()
                    .setVertx(vertx).setHttpServer(httpServer).setRouter(router);

    //Now just inject it into the vertxHttpServerBuilder before you call build
    HttpServer httpServer = vertxHttpServerBuilder.build();
    managedServiceBuilder.setHttpServer(httpServer);
Read Vertx guide on routing for more details Vertx Http Ext Manual.

Where do we go from here

QBit has a health system, and a microservices stats collections system. Vertx 3 provided similar support. QBit has an event bus. Vertx has an event bus. There is no reason why QBit can't provide Vertx implementations of its event bus (this is how the QBit event bus started), or for that matter integrate with Vertx's health system or its stats collection system. QBit has its own service discovery system with implementations that talk to DNS, Consul, or just monitor JSON files to be updated (for Chef Push, or Consul, etcd pull model). There is no reason QBit could not provide an implementation of its Service Discovery that worked with Vertx's clustering support. All of the major internal services that QBit provides are extensible with plugins via interfaces. There is plenty of opportunity for more integration of QBit and Vertx.
QBit and Vertx have both evolved to provide more and more support for microservices and there is a lot of synergy between the two libs.
QBit can also play well with Servlets, Spring MVC, Spring Boot, and other lightweight HTTP libs. QBit comes batteries included.

Find out more information on QBit here.

No comments:

Post a Comment

Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training