我有一个用 C# 编写的 ASP.NET 3.5 服务器应用程序。它使用 HttpWebRequest 和 HttpWebResponse 向 REST API 发出出站请求。
我已经设置了一个测试应用程序以在单独的线程上发送这些请求(以模糊地模仿服务器的并发性)。
请注意,这更像是一个 Mono/Environment 问题而不是代码问题;所以请记住,下面的代码不是逐字记录的;只是功能位的剪切/粘贴。
这是一些伪代码:
// threaded client piece
int numThreads = 1;
ManualResetEvent doneEvent;
using (doneEvent = new ManualResetEvent(false))
{
for (int i = 0; i < numThreads; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Test), random_url_to_same_host);
}
doneEvent.WaitOne();
}
void Test(object some_url)
{
// setup service point here just to show what config settings Im using
ServicePoint lgsp = ServicePointManager.FindServicePoint(new Uri(some_url.ToString()));
// set these to optimal for MONO and .NET
lgsp.Expect100Continue = false;
lgsp.ConnectionLimit = 100;
lgsp.UseNagleAlgorithm = true;
lgsp.MaxIdleTime = 100000;
_request = (HttpWebRequest)WebRequest.Create(some_url);
using (HttpWebResponse _response = (HttpWebResponse)_request.GetResponse())
{
// do stuff
} // releases the response object
// close out threading stuff
if (Interlocked.Decrement(ref numThreads) == 0)
{
doneEvent.Set();
}
}
如果我在 Visual Studio Web 服务器中的本地开发机器(Windows 7)上运行应用程序,我可以增加 numThreads 并接收相同的平均响应时间,而无论是 1 个“用户”还是 100 个,变化最小。
将应用程序发布并部署到 Mono 2.10.2 环境中的 Apache2,响应时间几乎呈线性增长。(即,1 个线程 = 300 毫秒,5 个线程 = 1500 毫秒,10 个线程 = 3000 毫秒)。无论服务器端点(不同的主机名、不同的网络等)如何,都会发生这种情况。
使用 IPTRAF(和其他网络工具),应用程序似乎只打开 1 或 2 个端口来路由所有连接,其余响应必须等待。
我们已经构建了一个类似的 PHP 应用程序并部署在 Mono 中,具有相同的请求并且响应可以适当地扩展。
我已经完成了我能想到的 Mono 和 Apache 的每一个配置设置,并且两个环境之间唯一不同的设置(至少在代码中)是有时 Mono 中的 ServicePoint SupportsPipelining=false,而从我的机器。
似乎由于某种原因在 Mono 中没有更改 ConnectionLimit(默认值为 2),但我在代码和指定主机的 web.config 中将其设置为更高的值。
要么我和我的团队忽略了一些重要的事情,要么这是 Mono 中的某种错误。