Nov 18, 2023
Vertx Logo
Vert.x is a toolkit that provides a set of libraries and utilities to build reactive applications that run on Java Virtual Machine (JVM) . These applications are resource-efficient, concurrent, and contain flexible features.
Reactive applications are event-driven, i.e., they respond to changes or events in an asynchronous and non-blocking way.
You must have read some articles calling vert.x a framework, but that is not exactly true. It is a toolkit, and there is a difference between a framework and a toolkit. A framework usually imposes a certain structure or convention on how the application should be organized, while a toolkit gives more freedom and flexibility to developers to choose the component and design.
Vert.x is called a "Polyglot" toolkit because it supports multiple programming languages and paradigms. Some of the languages it supports are Java, Kotlin, JS, Groovy, Ruby, etc.
It is like a collection of Lego bricks that can be assembled in various ways, rather than a pre-built model that has a fixed shape and function.
Well, it handles it by using a reactive and event-driven approach. It uses the following concept to achieve high performance and scalability:
It is a thread that runs in an infinite loop, checking for and dispatching events to the appropriate handlers. Now, you might ask, what is an event or a handler?
Events can be network IO, file IO, timers, messages, etc. Whereas handlers are pieces of code that are registered by the application to handle specific events.
Let's take an example to understand it better. Say you have written a piece of code that runs whenever you receive a response from a server. First, you send the request to the server and go on doing some other task. As soon as the server sends you the response, your piece of code will run. Here, the server response is an event, and the piece of code that ran is your handler.
Note: the event loop must never be blocked by any handler. Otherwise, it will affect the responsiveness of the entire system.
Vert.x uses one event loop per core by default, which means that each event loop thread can handle a lot of concurrency using a small number of kernel threads. This increases the efficiency and throughput of the application significantly.
Since we are not allowed to run long-running tasks on an event loop, there has to be a way to address this. Vert.x provides worker threads for that. These can be used to execute blocking or long-running tasks that would otherwise block the event loop threads.
Worker threads are managed by vert.x, and the application can specify how many worker threads it needs and how to deploy them.
But how does the worker thread communicate with the main thread? The answer lies in the event bus, which is a distributed and lightweight messaging system that allows different components to exchange messages in a publish-subscribe or point-to-point fashion.
Worker threads can also use callbacks and future to handle the results of the tasks.
Vert.x provides two ways to use worker threads:
1vertx.executeBlocking(future -> {
2 // check the thread that is executing this task
3 System.out.println(Thread.currentThread().getName());
4 try {
5 // do some task that takes a long time to complete
6 Thread.sleep(1000);
7 } catch (InterruptedException e) {
8 throw new RuntimeException(e);
9 }
10 future.complete();
11 }, result -> {
12 System.out.println(result.succeeded());
13});
As touched earlier, they are the basic units of deployment and execution in Vert.x.
They are chunks of code that can be written in different languages, and they can be deployed by Vert.x in different ways. Verticles can be deployed as standard verticles, which run on the event loop threads, or as worker verticles, which run on the worker threads.
Verticles are loosely coupled and communicate with each other via the event bus. Verticles can also use shared data structures, such as maps and counters, to coordinate their state. Verticles are designed to be scalable and fault-tolerant, and they can be deployed across multiple nodes in a cluster.
Let's create a Test Verticle that spins up an HTTP Server
1public class TestVerticle extends AbstractVerticle {
2 @Override
3 public void start() {
4 // we are creating a simple HTTP server that listens
5 //on 9090 port using the verticle
6 vertx.createHttpServer().requestHandler(req -> {
7 req.response().end("Hello from Vert.x!");
8 }).listen(9090, result -> {
9 if (result.succeeded()) {
10 System.out.println("HTTP server started on port 9090");
11 } else {
12 System.out.println("Failed to start HTTP server");
13 }
14 });
15 }
16}
Having created this verticle, we need to run it. We can create a main function (the entry point) and define the following snippet. This will execute the verticle
1public static void main(String[] args) {
2 Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(10));
3 vertx.deployVerticle(new TestVerticle());
4}
If you open your browser and navigate to http://localhost:9090 you'll see the following message
The event bus in Vert.x is a lightweight distributed messaging system that allows different parts of your application, or different applications and services, to communicate with each other in a loosely coupled way. The event bus supports the following communication patterns:
The event bus allows verticles to communicate with each other via messages.
Messages have a body and optional headers for storing metadata. Messages can be of any type, such as strings, buffers, JSON objects, etc. Vert.x provides a set of default codecs for encoding and decoding common types of messages and also allows the developer to register custom codecs for their own types. Codecs are responsible for serializing and deserializing messages, and they can also transform messages during the process. Codecs are useful for handling different formats of messages, such as XML, CSV, Protobuf, etc.
The event bus supports various types of transports, such as TCP, HTTP, WebSocket, etc. The event bus also enables Vert.x to scale across multiple nodes in a cluster by using a cluster manager, such as Hazelcast or Infinispan, to discover and connect the nodes. The event bus ensures that the messages are delivered reliably and consistently across the cluster.
In conclusion, Vert.x is a toolkit for building reactive applications on the JVM with resource-efficient, concurrent, and flexible features. It supports multiple languages, such as Java, Kotlin, Scala, Ruby, and JavaScript, and provides a rich ecosystem of modules and clients for various tasks, such as web APIs, databases, messaging, cloud, security, and more.
It uses the concepts of event loop, worker threads, verticles, and event bus to handle a lot of concurrency and scalability using a small number of kernel threads, which increases the efficiency and throughput of the application significantly. Vert.x also gives the developer a lot of flexibility and choice to design and implement the application according to their needs and preferences. It is one of the fastest and most scalable Java frameworks today, and it is suitable for building reactive, distributed, and microservice-based applications.
If you want to learn more about Vert.x, you can check out the official official website or the documentation .
References:
Subscribe to the newsletter to learn more about the decentralized web, AI and technology.
Please be respectful!