<aside> 💡

一个Vert.x应用程序由一个或者多个Vertical构成,每个Vertical都是一个用于处理异步事件的单元。通常我们会根据业务功能或者涉及的技术来对Verticle进行分工,例如,一个Verticle用于提供HTTP API,而另一个Verticle用于处理数据存储。这种设计鼓励大家为给定的Verticle部署多个实例,以达到可拓展性。

那么问题来了,由于每一个Verticle的功能都很单一,那么各个不同功能的Vertical之间要进行数据交换,要进行通信该怎么办?

Vert.x提供了一个叫做事件总线(EventBus)的东西来解决这个问题,事件总线是负责将Verticle连接起来确保它们可以互相协作的角色。借助事件总线,开发人员可以在程序内部以及网络上的多个节点之间实现分布式的事件处理,对于使用者来说,这一切都是透明的。

</aside>

📝 主旨内容

什么是事件总线?

事件总线是一种异步地发送和接收消息的机制。消息的发送和接收都有一个相应的目标地址。目标地址只是一个任意形式的字符串,如:abc.def.ghi或者abc-def-ghi,通常我们选择带有点号的前一种格式。

事件总线怎么使用?

1、点对点(Point-to-Point)模式

模式描述:

✅ 优势

✔ 适用于 一对一任务分配(单个消费者处理)。

✔ 适用于 负载均衡(多个消费者可以轮流接收请求)。

✔ 保证消息不会被多个消费者重复处理。

❌ 劣势

✖ 不能广播消息,多个消费者不会同时收到消息。

✖ 如果接收者崩溃,可能导致消息丢失(除非使用 DeliveryOptions 设置重试机制)。

📌 适用场景

示例代码如下:

public class SenderVerticle extends AbstractVerticle {
    @Override
    public void start() {
        vertx.setPeriodic(2000, id -> {
            JsonObject message = new JsonObject().put("content", "Hello from Sender!");
            vertx.eventBus().send("address.message", message);
            System.out.println("Sent message: " + message.encode());
        });
    }
}

receiver示例代码

public class ReceiverVerticle extends AbstractVerticle {
    @Override
    public void start() {
        vertx.eventBus().consumer("address.message", message -> {
            JsonObject body = (JsonObject) message.body();
            System.out.println("Received message: " + body.encode());
        });
    }
}

测试启动入口

public class MainVerticle  {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        //vertx.deployVerticle(new MainVerticle());
        vertx.deployVerticle(new SenderVerticle());
        vertx.deployVerticle(new ReceiverVerticle());
    }
}

2、发布-订阅(Publish-Subscribe)模式

模式描述:

✅ 优势

✔ 支持广播,多个消费者可以同时接收同一条消息。

✔ 适用于事件驱动架构,让多个组件监听同一事件。

✔ 解耦生产者与消费者,发送者不关心谁接收了消息。

❌ 劣势

✖ 无法保证所有订阅者都能成功处理消息(如果某个消费者崩溃,它不会影响其他消费者)。

✖ 无法负载均衡(所有订阅者都收到相同消息,不能自动分配任务)。

✖ 可能导致消息泛滥,影响系统性能(尤其是高频发布的情况下)。

📌 适用场景

示例代码如下:

public class PublisherVerticle extends AbstractVerticle {

    @Override
    public void start() {
        vertx.setPeriodic(3000, id ->{
            JsonObject message = new JsonObject().put("temp", 25 + Math.random() * 10);
            vertx.eventBus().publish("publish.update", message);
            System.out.println("Published message: " + message.encode());
        });
    }
}

Subscriber1示例代码

public class Subscriber1Verticle extends AbstractVerticle {
    @Override
    public void start()  {
        vertx.eventBus().consumer("publish.update", message -> {
            System.out.println("Subscriber 1 received: " + message.body());
        });
    }
}

Subscriber2示例代码