0

何千もの異なるクライアントから送信された UDP イベントにアプリが反応するようにしたいと考えています。各クライアントは、5 ~ 10 秒ごとに 1 ~ 10 個の UDP パケットを送信します。各パケットは非常に迅速に処理されます (主にメモリと小さな計算で、redis を使用し、たまに DB 呼び出しを行うだけです)。呼び出し元にデータが返されることはありません。

wikiで説明されているように、Reactor を Spring に実装しました。次に、Spring Integration ドキュメントで説明されているように、UDP インバウンド チャネルを実装しました。構成は次のとおりです。

<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メッセージ ストア(記事の下部) は役に立ちますか? そして、リアクターでこのパケットをクランチするメソッドが遅い場合はどうなりますか?

4

2 に答える 2

3

Reactor ではまだ UDP を直接サポートしていないため、イベントを Reactor にパブリッシュするための抽象化は非常に賢明です。ただし、「ボーナスの質問」で、ドメイン固有の方法で管理する必要があるパブリッシャー/コンシューマーのスループットに問題があることに注意してください。そこに特効薬はありません。

あなたのユースケースでは、実際にはProcessor [1]の方が適していると言いたくなるでしょう。プレーンで発生する動的なセレクターベースのディスパッチを回避するため、データ処理の全体的なスループットが大幅に向上しますReactor。何らかのトピック基準に基づいて着信イベントを別のハンドラーにディスパッチする場合を除き、代わりにそれを確認することをお勧めします。スループットが高くなれば、Consumer が追いつくことについて心配する必要が少し減ります (ただし、Consumer何も自動的に高速化できない非常に遅い処理を行っている場合を除きます)。

しかし、本当にバックログを管理する必要がある場合は、プロデューサーとコンシューマーをQueue. Reactor にはPersistentQueue [2]抽象化があり、JavaChronicle [3]を使用してオブジェクトを公開し、ディスクに永続化できます。これは、aConsumerを使用して aに排出できます( 1.0 の準備が整うと、今週中Pollerに javadoc が公開されます...Poller以前はPipe [4]と呼ばれていました)。

于 2013-11-04T15:00:09.867 に答える