我的系统有两种不同类型的消息 - 类型 A 和 B。每个消息具有不同的结构 - 类型 A 包含一个 int 成员,而类型 B 包含一个 double 成员。我的系统需要将这两种类型的消息传递给多个业务逻辑线程。减少延迟非常重要,因此我正在研究使用 Disruptor 以机械方式传递消息从主线程到业务逻辑线程。
问题在于 disruptor 只接受环形缓冲区中一种类型的对象。这很合理,因为 disruptor 预先分配了环形缓冲区中的对象。然而,这也使得通过 disruptor 向业务逻辑线程传递两种不同类型的消息变得困难。据我所知,我有四个选择:
1. 配置 disruptor 使用包含 固定大小的字节数组 的对象(正如 How should one use Disruptor (Disruptor Pattern) to build real-world message systems? 推荐的那样)。在这种情况下,主线程必须将消息编码为字节数组,然后将其发布到 disruptor 中,每个业务逻辑线程在收到消息后都必须将字节数组解码回对象。这种设置的缺点是业务逻辑线程不是真正共享 disruptor 的内存 - 而是从 disruptor 提供的字节数组创建新对象(从而创建垃圾)。这种设置的优点是所有业务逻辑线程都可以从同一个 disruptor 中读取多种不同类型的消息。
2. 配置 disruptor 使用单个类型的对象,但创建 多个 disruptors,每种对象类型都有一个 disruptor。在上面的例子中,将会有两个独立的 disruptor - 一个用于类型 A 的对象,另一个用于类型 B 的对象。这种设置的优点是主线程无需将对象编码为字节数组,业务逻辑线程少创建垃圾,因为它们可以共享 disruptor 中使用的相同对象。这种设置的缺点是每个业务逻辑线程都要订阅来自多个 disruptors 的消息。
3. 仅使用一种类型的消息,并且在消息中包含一个标识符,以告知业务逻辑线程消息的类型。在收到消息后,业务逻辑线程必须根据标识符对消息进行分类处理。这种设置的优点是简单,但它可能会影响性能,因为分类处理可能会导致延迟增加。
4. 重构系统设计,使得只有一种类型的消息存在。如果这种方案可行,那么肯定是最好的选择。
问题在于 disruptor 只接受环形缓冲区中一种类型的对象。这很合理,因为 disruptor 预先分配了环形缓冲区中的对象。然而,这也使得通过 disruptor 向业务逻辑线程传递两种不同类型的消息变得困难。据我所知,我有四个选择:
1. 配置 disruptor 使用包含 固定大小的字节数组 的对象(正如 How should one use Disruptor (Disruptor Pattern) to build real-world message systems? 推荐的那样)。在这种情况下,主线程必须将消息编码为字节数组,然后将其发布到 disruptor 中,每个业务逻辑线程在收到消息后都必须将字节数组解码回对象。这种设置的缺点是业务逻辑线程不是真正共享 disruptor 的内存 - 而是从 disruptor 提供的字节数组创建新对象(从而创建垃圾)。这种设置的优点是所有业务逻辑线程都可以从同一个 disruptor 中读取多种不同类型的消息。
2. 配置 disruptor 使用单个类型的对象,但创建 多个 disruptors,每种对象类型都有一个 disruptor。在上面的例子中,将会有两个独立的 disruptor - 一个用于类型 A 的对象,另一个用于类型 B 的对象。这种设置的优点是主线程无需将对象编码为字节数组,业务逻辑线程少创建垃圾,因为它们可以共享 disruptor 中使用的相同对象。这种设置的缺点是每个业务逻辑线程都要订阅来自多个 disruptors 的消息。
3. 仅使用一种类型的消息,并且在消息中包含一个标识符,以告知业务逻辑线程消息的类型。在收到消息后,业务逻辑线程必须根据标识符对消息进行分类处理。这种设置的优点是简单,但它可能会影响性能,因为分类处理可能会导致延迟增加。
4. 重构系统设计,使得只有一种类型的消息存在。如果这种方案可行,那么肯定是最好的选择。
将 disruptor 配置为使用一个包含消息 A 和 B 所有字段的"超级"对象的单个类型。这非常违反面向对象的风格,但会在选项#1和#2之间取得折衷。
将 disruptor 配置为使用对象引用。但在这种情况下,我失去了对象预分配和内存排序带来的性能优势。
你对此情况有什么建议?我觉得选项#2是最简洁的解决方案,但我不知道消费者是否可以技术上订阅来自多个 disruptor 的消息。如果有人能提供关于如何实现选项#2的示例,那将不胜感激!