0

I have a simple Vertx program that runs in a clustered mode with integrated Hazelcast. In this program, the event-bus is used for event propagation. When a request is received on port 18081, an event is published, and this event is consumed and the request path is printed.
Now, I'm deploying this program and setting up two replicas to run simultaneously. In this case, if an event is published, it will be consumed by both replicas at the same time.
However, my goal is to ensure that only one replica of the same program consumes the event. It should be similar to a consumer group, where only one consumer instance ultimately consumes the event.
One possible solution is to use eventBus.send() instead of eventBus.publish(). Unfortunately, I also want the event to be consumed by different types of services simultaneously, so using send doesn't meet my requirements.

Is there any way to achieve the goal?

Code

package org.example;

import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.http.HttpServer;
import io.vertx.core.spi.cluster.ClusterManager;
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;

public class SlaveNode {

    public static final String MY_ADDRESS = "my.address";

    public static void main(String[] args) {
        ClusterManager mgr = new HazelcastClusterManager();
        VertxOptions options = new VertxOptions().setClusterManager(mgr);

        Vertx.clusteredVertx(options, res -> {
            if (res.succeeded()) {
                Vertx vertx = res.result();
                EventBus eventBus = vertx.eventBus();

                // subscribe address event
                eventBus.consumer(MY_ADDRESS, event -> {
                            Object body = event.body();
                            System.out.println("receive event: " + body);
                        });


                HttpServer server = vertx.createHttpServer();
                server.requestHandler(event -> {
                    // publish address event
                    vertx.eventBus().publish(MY_ADDRESS, "publish: " + event.absoluteURI());
                    event.response().end("success");
                });
                server.listen(18081);

            } else {
                // failure
            }
        });
    }

}

I have been trying to find if there are any relevant configurations that can identify multiple replicas as the same application, but I haven't found any such configuration.

张Del
  • 1
  • Vert.x event bus is designed to be used as either publish/subscribe or peer-to-peer way. There is no consumer group support. You can implement it by using a coordination mechanism such as a distributed lock on the consumer side. The consumers race for the lock and the one that gets it processes the message. However this is not a really good implementation. Another way is you can publish the message with a key for example an integer. One consumer processes the odd, the other processes even numbers. Essentially the message is still delivered but discarded by the consumer. I hope this helps. – Orçun Çolak Jul 14 '23 at 07:58
  • Thank you very much. It seems that there isn't a convenient way to do that. Perhaps I should integrate with Kafka, and if the Vert.x event bus supports it, that would be very helpful. – 张Del Jul 17 '23 at 02:45

0 Answers0