2012-11-29 56 views
8

我目前正在开发一个简单的P2P网络作为练习。网络中的每个节点都会将心跳发送到其他节点的子集,以便能够检测已离开网络的节点。除了心跳数据包之外,当新节点加入/离开网络时,当他们想要查找资源(小文本文件)等时,我会发送数据包。所有数据包都是UDP数据包。处理很多传入数据包的最佳方法

每当我收到一个数据包,我开始一个新的线程来处理特定数据包。然而,我担心的是在一个应用程序生命周期中开始的线程数量增加了很多(尤其是因为心跳)。 (也有我想避免的死锁之类的风险)。

我想到有一个队列或者我把所有的报文,并有一个单独的线程处理所有的数据包一次一个从队列(类似生产者 - 消费者模式)的东西。我希望数据包得到快速处理,因此发送者不会认为数据包丢失。

什么是处理很多不同的传入数据包,而无需启动为他们每个人一个新的线程的最佳方式?我应该用我拥有的东西,生产者消费还是不同的东西?

+1

当然。使用生产者 - 消费者和LinkedList。我能想到的最简单的方法。 – DankMemes

+0

你可以从你自己提到的方式开始,做一些基准,然后尝试最新的东西,比如“Disruptor”(http://lmax-exchange.github.com/disruptor/),然后再做一些基准。 –

+1

它可能有助于量化“许多不同的传入数据包”......相对而言,当现代系统通常可以处理每秒数百到数千个数据包(取决于您的NIC的数量和类型)时,心跳应该不会太多。我怀疑心跳可能会在几十分钟的范围内... – twalberg

回答

0

处理一个数据包需要多长时间?

对于ping那些它可能更快,只是处理它们,因为他们收到,你可以把别人共享数据结构是这样的一个特定的阻塞队列,所以当队列为空时,工作线程等待新工作,当一个新工作被添加时,一个线程被唤醒并且将完成工作。

可能开始每包一个线程使你消耗的启动和停止线程比实际做的工作更多的时间。

如果对于所有类型的数据包来说,响应数据包所要做的事情并不那么耗时,那么可能会发生这样的情况,即队列和调度线程的锁所花费的额外时间会使您的程序变得更慢而不是更快。

在任何情况下使用线程池,在一开始启动的工人。如果您希望可以根据过去几分钟的负载动态地增加或减少工作线程的数量。

+0

时间稍有不同。大多数数据包都是快速处理的,但有些操作涉及到新数据包的发送和期待响应。但是我想我会和线程池和队列一起去。谢谢。 – Wondering

0

我会用一个event driven architecture。为每个数据包创建一个新的线程是不可扩展的,所以这将工作到一定的工作量,但有一点它不会工作了。你可以比较一下像Facebook聊天这样的聊天程序,其中消息是数据包。 事件驱动的体系结构可以扩展,恕我直言,你正在寻找什么。只要做一些Google搜索,那里有许多编程语言的库,所以只需为您选择合适的一个(我喜欢在Erlang,Scala,C或Python中这样做)。

编辑:好的,没有看到java标签。但语言并不重要。

看看这个链接,例如: http://www.nightmare.com/medusa/async_sockets.html

我觉得这是一个相当不错的一个到达事件驱动编程的想法。

+0

但他使用UDP,所以他可能只有一个文件描述符。 – LtWorf

+0

这并不排除使其异步的可能性。寻找非阻塞套接字,异步I/O或甚至事件驱动套接字(基本上描述所有相同的想法)。 – Cravid

+0

我知道这样做还是有可能的,但我不确定在这种特殊情况下值得一提。 – LtWorf