我的C#程序通过多个套接字接收大量数据,看来我遇到了Windows内核上的TCP缓存过载的问题。
这可以通过服务器的tcpdump的以下结果看出:
18:02:18.963370 IP xxxx> yyyy.zzz :. ack 10017011 win 0
您将使用哪种数据结构/策略来缓存读取数据以避免C#过载?
我目前正在为每个读取记录后调用的单独线程中的每个套接字使用委托,但这似乎是一个问题,因此我可能需要将其拆分为两个线程。
或者我应该考虑调整Windows端的TCP参数?我使用的是Windows 7.
是否有任何内核优化书籍?
我真的很傻,即使整机负载大约为20-25%,最高负载核心负载大约为50-60%,程序也会变慢。
答案 0 :(得分:4)
如果不了解程序的架构太多,我猜你的程序本身就是瓶颈。如果您的应用程序不使用后台工作程序来收集TCP消息并将它们存储以供执行“繁重”的代码使用,那么您的程序正在读取现有缓冲区,然后处理TCP缓冲区重新填充时的内容。这种恶性循环只能有一个结局;最终缓冲区将在等待程序完成上次处理时的溢出时溢出。
我会考虑将您的TCP接收重构为ETL类型的模型。您需要一个线程,其作用是侦听TCP输入,从缓冲区中提取数据并将其排入一个对程序其余部分可见的集合中。除了从缓冲区中抽出数据并将原始消息推送到此队列之外,它应该不做任何其他事情,它应该尽可能快地执行此操作。
通过在内存中接收到的消息,您的程序的其余部分几乎可以消耗每条消息所需的时间。您仍然必须确保不要重载此内存中队列,但由于单个.NET对象可以引用最多2GB的内存,因此您遇到麻烦的可能性要小得多。如果你正在溢出这个程序内队列,你需要考虑使处理更有效,或者在流程的第二阶段抛出更多线程。