Vert.x Distributed Microservices with Java.

Distributed Systems Development A-Z Guide.

Dmytro Nasyrov
Pharos Production
6 min readFeb 24, 2019

--

Give us a message if you’re interested in Blockchain and FinTech software development or just say Hi at Pharos Production Inc.

Or follow us on Youtube to know more about Software Architecture, Distributed Systems, Blockchain, High-load Systems, Microservices, and Enterprise Design Patterns.

Pharos Production Youtube channel

In our previous Vert.x articles we have looked at how to install Vert.x for development purposes and at simple RESTful service with Vert.x. If you have missed it, check it out.

Vert.x JVM Framework. MacOS installation Guide.

Vert.x RESTful Services on Java

This time we will develop a new microservice inside our project. Every new module has its own EventBus and in order to send messages between modules, we have to join them into the cluster. The first microservice is our REST API, the second microservice will be prepared for RocksDB integration. We will send GET and POST queries to the first one, then request a data from the second microservice via event bus, and return this data to the user.

RocksWorker.

Let’s add a new Maven module and create a package and add several classes. We will need several new class and one configuration file:

  • RocksService interface and implementation — this is the definition of our future service;
  • RocksServiceVerticle — we have to deploy the service, we can do this via a verticle
  • Package-info.java — configuration file that defines auto-generation settings for two new useful classes, that Vert.x will create for us.
New Maven module.

One more thing, to the global Maven configuration file, let’s add 3 new dependencies.

  • vertx-service-proxy — this one creates a proxy for us. A proxy allows giving access to the isolated functionality from the outside world;
  • vertx-codegen — this dependency adds a possibility to generate tons of boilerplate code just with a couple of annotations;
  • vertx-hazelcast — this dependency creates a cluster for us.
New dependencies.

Let’s add cluster settings to the common package. This is an XML file in the resources directory. We will not go deep inside cluster settings today, please refer to Vert.x documentation to know more about Hazelcast and cluster.xml.

cluster.xml

Let’s take a look at package-info.java file. This file defines settings for boilerplate code generation. Here we say that module rocksworker contains classes to be generated.

Information for a boilerplate generator.

Let’s define RocksService interface. The interface is straightforward. We define two string constants — the name and the address on event bus of our service. Also, we want to define two asynchronous methods to get and to create a user. Both methods don’t return anything but instead of that act asynchronously via handlers.

RocksService interface.

In the implementation of the interface in both methods, we return futures with placeholder responses. Both objects in responses will be replaced by RocksDB calls in the next article.

RocksService implementation.

To define a verticle extended from our Microservice verticle class, we need to add the Common module as a dependency.

Common module.

Let’s add one more method to the MicroserviceVerticle class. It will be used to publish information about new event bus service into service discovery.

Publish an event bus service.

Let’s go through RocksServiceVerticle. First of all, it’s extended from MicroserviceVerticle.

RocksServiceVerticle.

We define two global variables here. One is for binding the service to the address, another one is to manage consumer, e.g. get rid of it into the stop method.

Global variables.

We override the start method. Here we create a new instance of RocksService. Then create a ServiceBinder to bind the service to the address. Then we register service in ServiceBinder instance. And the last thing we do — we publish information about newly created service into service discovery.

Publish a new service.

On successful completion, we call a handler which will inform us about a new service appeared, just for the sake of clarity.

New service published. Or not.

Mobile API.

In the Mobile API module, we need to add a new dependency — our RocksWorker module.

RocksWorker module.

In ServerVerticle we add a new global variable that will represent a RocksService instance.

Global variables.

We create a new service through ServiceProxyBuilder class.

New Service.

Let’s change handleRequest method to make possible to handle both GET and POST requests.

handleRequest method.

We define GET handler like this. We request a user from RocksService and respond with 200 and payload or 404 and nothing when a user is not found.

GET

The same with the post request. We take userId from parameters, call RocksService and respond with 201 and new ID or 422 — unprocessable entity.

POST

Cluster.

To make things work together, we have to add one small method Launcher class. Before Vert.x will initiate its instance we inject clustering mode into options and define a cluster host to localhost.

Cluster.

Let’s Try It.

To run the new service we need to create a new Application which will start the corresponded verticle.

RocksWorker application.
RocksWorker application settings.

We’re ready to go! Run both microservices and try to send both requests.

GET
POST

We have learned how to make two microservices communicate via event bus. You can find the full source code at our Github repo.

Thank you for reading!

--

--

Dmytro Nasyrov
Pharos Production

We build high-load software. Pharos Production founder and CTO.