Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run multiple vertices in Vert.x?

I am new to Vert.x and I want to run multiple verticles through jar. I have two files, one is MyFirstVertice.java and it routes the path "/q1/" and return something. The second is MySecondVertice.java which routes the path "/q2/". The second vertice is deployed in the first vertice.

MyFirstVertice.java

public class MyFirstVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> fut) throws Exception {

    HttpServer server = vertx.createHttpServer();
    Router router = Router.router(vertx);
    router.route("/q1/*").handler(routingContext -> {
        HttpServerRequest request = routingContext.request();
        String Y = request.getParam("key");
        String cipherText = request.getParam("message");

        HttpServerResponse response = routingContext.response();

        response.setChunked(true);
        response.putHeader("content-type", "text/plain");
        response.write(Y + "\n");
        response.write(cipherText + "\n");
        response.end();

        vertx.deployVerticle(new MySecondVerticle(), stringAsyncResult -> {
            System.out.println("Second verticle is deployed successfully.");
        });
    });

    server.requestHandler(router::accept).listen(8080, httpServerAsyncResult -> {
        if (httpServerAsyncResult.succeeded()) {
            fut.complete();
        } else {
            fut.fail(httpServerAsyncResult.cause());
        }
    });
}

}

MySecondVetice.java

public class MySecondVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> fut) throws Exception {

    HttpServer server = vertx.createHttpServer();
    Router router = Router.router(vertx);
    router.route("/q2/*").handler(routingContext -> {
        HttpServerResponse response = routingContext.response();
        response.setChunked(true);
        response.putHeader("content-type", "text/plain");

        response.end("q2");
    });

    server.requestHandler(router::accept).listen(8080, httpServerAsyncResult -> {
        if (httpServerAsyncResult.succeeded()) {
            fut.complete();
        } else {
            fut.fail(httpServerAsyncResult.cause());
        }
    });
}

}

My pom.xml

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <manifestEntries>
                                    <Main-Class>io.vertx.core.Starter</Main-Class>
                                    <Main-Verticle>tutorial.diluo.MyFirstVerticle</Main-Verticle>
                                </manifestEntries>
                            </transformer>
                        </transformers>
                        <artifactSet/>
                        <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
                    </configuration>
                </execution>
            </executions>
        </plugin>

I run it through java -jar xxx-fat.jar.

When I type localhost:8080/q1/xxx in the browser, it can return desired content. But when I am trying to visit localhost:8080/q2/xxx, it says "Resource Not Found". Can you tell me how to deploy two verticles that route different paths? I know that I can route different pathe in the same verticle, I just want to know how to deploy and run multiple vertices. Thanks in advance!

like image 203
dibugger Avatar asked Oct 29 '25 01:10

dibugger


1 Answers

The problem you have is that both Verticles are attempting to bind to the same port (8080) which you can't do. So the second Verticle is likely throwing a BindException and failing to come up. The first Verticle then, doesn't have a resource at /q2 which is why you're getting the Resource Not Found.

Updated as per comment from tsegismont:

Vert.x allows multiple Verticles to start on the same port in a feature known as server sharing. When this happens, Vert.x will use a round robin strategy to send requests to each Verticle in turn. So, you should see 50% of requests working for /q1 and 50% of request for /q2. But - as noted by tsegismont, your browser uses persistent connections so it maintains a connection to a single Verticle. You should find that using curl, or another browser may give you a better result. Either way, this isn't probably what you want.

You should have a think if you need 2 Verticles. Generally you want to think of a Verticle as an entry point in to your application - it's a way of bootstrapping your application / microservice.

If you really need 2 Verticles then you will have to choose separate ports or run on separate boxes. If you don't, then just create 2 routes on the same router.

See http://vertx.io/docs/vertx-web/java/ for more info on Vert.x Web

like image 144
Will Avatar answered Oct 31 '25 16:10

Will



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!