我的系统有两种不同类型的消息——类型 A 和 B。每条消息都有不同的结构——类型 A 包含一个 int 成员,类型 B 包含一个 double 成员。我的系统需要将这两种类型的消息传递给众多业务逻辑线程。减少延迟非常重要,因此我正在研究使用 Disruptor 以机械方式将消息从主线程传递到业务逻辑线程。
我的问题是破坏者只接受环形缓冲区中的一种对象。这是有道理的,因为中断器预先分配了环形缓冲区中的对象。但是,通过 Disruptor 将两种不同类型的消息传递给我的业务逻辑线程也很困难。据我所知,我有四个选择:
配置中断器以使用包含固定大小字节数组的对象(如How should one use Disruptor (Disruptor Pattern) to build real-world message systems?推荐的那样)。在这种情况下,主线程必须在将消息发布到中断器之前将消息编码为字节数组,并且每个业务逻辑线程必须在接收时将字节数组解码回对象。这种设置的缺点是业务逻辑线程并没有真正共享破坏者的内存——而是从破坏者提供的字节数组中创建新对象(从而产生垃圾)。这种设置的好处是所有业务逻辑线程都可以从同一个中断器中读取多种不同类型的消息。
将中断器配置为使用单一类型的对象,但创建多个中断器,每个对象类型一个。在上面的例子中,会有两个独立的破坏者——一个用于类型 A 的对象,另一个用于类型 B 的对象。这种设置的好处是主线程不必将对象编码为字节数组,并且业务较少的逻辑线程可以共享与中断器中使用的相同的对象(不创建垃圾)。这种设置的缺点是每个业务逻辑线程必须以某种方式订阅来自多个破坏者的消息。
将中断器配置为使用包含消息 A 和 B 的所有字段的单一类型的“超级”对象。这非常不符合 OO 风格,但允许在选项 #1 和 #2 之间进行折衷。
配置中断器以使用对象引用。但是,在这种情况下,我失去了对象预分配和内存排序的性能优势。
对于这种情况,您有什么建议?我觉得选项 #2 是最干净的解决方案,但我不知道消费者是否或如何在技术上订阅来自多个破坏者的消息。如果有人可以提供如何实施选项 #2 的示例,将不胜感激!