6

我正在研究一种应用程序,它需要一种类型的消息去击中数据库,另一种类型的消息去打一些外部xml api。HttpWebRequest和I/O完成端口

我必须处理一个很大的挑战之一是让HttpWebRequest类表现良好。我最初开始只使用标准的同步方法,并将整个线程化。这并不好。

那么一点阅读后,我看到推荐的方式做,这是使用的开始/结束的方法来工作委托给IO完成端口,从而释放线程池,并产生更好的性能。这似乎并不是这种情况...性能稍微好一些,但我相信与线程池相比,我完全看不到IO完成端口的使用。

我有一个线程轮换并向我发送线程池中可用的工作线程+完成端口。完成端口总是非常低(我见过的最大值是9),而且我总是使用大约120个工作线程(有时更多)。我用所有的方法httpwebrequest的开始/结束模式:

Begin/EndGetRequestStream 
Begin/EndWrite (Stream) 
Begin/EndGetResponse 
Begin/EndRead (Stream) 

我这样做对吗?我错过了什么吗?我可以同时使用(有时)多达2048个http连接(来自netstat输出) - 为什么完成端口号会很低?

如果有人可以给一些严肃的建议,关于如何做好这个管理工作者线程,完成端口和httpwebrequest将非常感激!

编辑:.NET是一个合理的工具吗?我可以获得大量的使用.NET和System.Net堆栈的httpconnections吗?有人建议使用类似WinHttp(或其他C++库)的东西,并从.NET中调用它,但这不是我特别想做的事情!

+0

您的外部API是否正确处理负载?我有一个外部服务,如果我发送太多的请求,服务服务器上的性能会有明显的下降。 – btlog 2011-01-26 14:13:36

+0

@btlog - >是的,好像我禁用了一些外部提供者,其他提供者产生更好的时间(但接收到相同的呼叫量)。如果问题是在他们身上,那么无论我对其他XML服务做什么都不会影响其他服务。 – peteisace 2011-01-27 07:08:03

回答

6

我的理解是,你不会捆绑一个I/O完成端口全部一个异步请求未完成的时间 - 只有当数据已被返回并正在处理相应的线程。希望你没有非常在回调中做很多工作,这就是为什么你在任何时候都没有很多使用中的端口。

您是否其实虽然表现不佳?你关心的仅仅是低数量吗?你是否获得了你期望的吞吐量?

有一个问题你可能有的是任何一个主机的HTTP连接池都比较小。如果您对同一台计算机有数百个请求,则默认情况下,一次只能创建2个请求实际上为,以避免DoS攻击相关主机(并获得保持活动的好处)。你可以通过编程或者使用app.config来增加它。当然,这可能不是问题,因为您已经解决了问题,或者因为您的所有请求都是针对不同的主机。 (如果netstat显示2048个连接,那听起来不错。)

0

也许您的EndRead方法应该只将结果写入线程安全队列,然后您可以从您控制的少量工作线程读取结果。和/或使用HttpWebRequest在完成时发出等待对象的信号这一事实,并编写自己的逻辑以等待来自单个(或少量)线程的所有未完成请求。

0

只有9个完成端口线程实际上意味着你可能正确和有效地使用它们。我假设你正在运行的机器有8个内核或4个超线程内核,这意味着操作系统会随时尝试保持最多8个活动(不是休眠/阻塞/等待)完成端口线程。

如果其中一个正在运行的线程变为非活动状态(sleep/block/wait)并且还有额外的工作项需要处理,那么会创建一个附加线程来将活动计数保持为8.如果看到9个线程,意味着您在完成端口线程的方法中实际上不会引入阻塞,并且实际上正在对它们执行CPU工作。

如果您有8个线程主动在8个内核上进行CPU绑定工作,那么添加更多线程只会减慢速度(线程之间的上下文切换将是浪费的时间)。

你应该注意的是为什么你有120 其他线程和他们在做什么。