在Spring中使用Reactor的UDP处理程序

时间:2013-11-03 02:57:33

标签: spring spring-integration reactor

我正在评估Spring,它正是新项目的生态系统。我希望我的应用程序对数千个不同客户端发送的UDP事件做出反应。每个客户端每5-10s发送1-10个UDP数据包。每个数据包将被并且应该被非常快速地处理(主要在内存和小型计算中,有助于redis,仅偶尔进行数据库调用)。不会向呼叫者返回数据。

我在Spring中实现了Reactor,就像他们在wiki上所描述的那样。 然后我实现了UDP入站通道,就像他们在Spring Integration文档中描述的那样。这是配置:

<int-ip:udp-inbound-channel-adapter id="receiverChannel"
                                    channel="stringConvert"
                                    port="9000"
                                    multicast="false"
                                    check-length="false"
                                    pool-size="10"
                                    lookup-host="false"
        />

<int:transformer id="convertChannel"
                 input-channel="stringConvert"
                 output-channel="toProcess"
                 ref="transformer"
                 method="transform"

        />

<int:service-activator input-channel="toProcess"
                       ref="accumulator"
                       method="accumulate"/>

<bean id="accumulator" class="hello.UDPAccumulator" />
<bean id="transformer" class="hello.UDPTransformer" />

然后在UDPAccumulator中我将该消息发布到reactor:

@Service
public class UDPAccumulator {

@Autowired
ReactorProducer producer;

public void accumulate(String quote) {
    producer.fireEvent(quote);

}

}

这是否是“正确”的方式,关于我想要高吞吐量? int-ip:udp-inbound-channel-adapter 的内部工作原理是什么?它可以在将消息传递到反应堆之前成为瓶颈吗?我看到反应堆有一些TCP相关的类和支持,但没有UDP。任何有关如何以最好的方式做到这一点的建议表示赞赏!

奖金问题。如果消息的发送速度快于发送到反应堆的消息,该怎么办? redis message store(文章底部)会有帮助吗?如果我在反应堆中压缩这些数据包的方法很慢呢?

2 个答案:

答案 0 :(得分:3)

由于我们尚未在Reactor中提供直接的UDP支持,因此将事件发布到Reactor的抽象是非常明智的。但是你在“奖金问题”中注意到发布商/消费者吞吐量存在问题,必须以特定领域的方式进行管理;那里没有银弹。

在您的使用案例中,我实际上很想说Processor [1]可能更合适。它为数据处理提供了更高的总体吞吐量,因为它绕过了在普通Reactor中发生的基于动态选择器的调度。除非您根据某些主题标准将传入事件分派给不同的处理程序,否则我建议您先查看。随着吞吐量的提高,您将不得不担心消费者跟不上(除非您的Consumer做的事情非常缓慢,没有什么可以自动加速)。

但是,如果你真的,真的需要管理积压,我建议通过Queue将你的生产者和消费者分开。 Reactor有一个PersistentQueue [2]抽象,您可以使用JavaChronicle [3]将对象发布到磁盘并保存到磁盘,然后可以使用{{1}将其排入Consumer (javadoc本周某个时候会出现Poller,因为我们已经准备好了1.0 ...以前称之为Poller [4])。

答案 1 :(得分:1)

我无法与Reactor对话,但UDP适配器有一个专用线程,可以读取原始数据包并将其移交给TaskExecutor。它会尽快完成此操作,以便它可以返回读取下一个数据包。

默认TaskExecutor是一个固定的线程池。

Reactor有DispatcherTaskExecutor可以注入适配器。

相同的任务执行程序用于主读取器线程和切换。