我使用System.Net.HttpListener BeginGetContext/EndGetContext同時處理多個http請求。這適用於我的16個核心Windows 7 SP1桌面,它可以同時處理16個請求。在Windows Server 2012 R2 16處理器VM上,20個請求中的前2個併發處理,然後按順序處理請求,例如,第三個請求的響應必須在請求第四個請求之前發送。異步使用的HttpListener同步行爲
我希望服務器以類似於桌面m/c即ie的方式處理請求。在8秒內處理20個請求,而不是當前的95秒。
以下日誌顯示了Windows 7機器上的行爲(良好)。客戶端和服務器進程都在Windows 7 m/c上運行。
這是客戶端日誌。每行包含客戶端的原始請求,並由服務器反饋回來,並添加服務器處理的時間。原始請求包含序列號和客戶發出請求的時間。
請注意,所有請求都是在小時過後的12:46分鐘進行的,16分鐘的響應時間是12:51,最後一個是12:54。
http://localhost:8894/dostuff?val=1-client-12:46-server-12:51
http://localhost:8894/dostuff?val=17-client-12:46-server-12:51
http://localhost:8894/dostuff?val=15-client-12:46-server-12:51
http://localhost:8894/dostuff?val=2-client-12:46-server-12:51
http://localhost:8894/dostuff?val=7-client-12:46-server-12:51
http://localhost:8894/dostuff?val=3-client-12:46-server-12:51
http://localhost:8894/dostuff?val=13-client-12:46-server-12:51
http://localhost:8894/dostuff?val=18-client-12:46-server-12:51
http://localhost:8894/dostuff?val=9-client-12:46-server-12:51
http://localhost:8894/dostuff?val=14-client-12:46-server-12:51
http://localhost:8894/dostuff?val=0-client-12:46-server-12:51
http://localhost:8894/dostuff?val=6-client-12:46-server-12:51
http://localhost:8894/dostuff?val=10-client-12:46-server-12:51
http://localhost:8894/dostuff?val=5-client-12:46-server-12:51
http://localhost:8894/dostuff?val=19-client-12:46-server-12:51
http://localhost:8894/dostuff?val=11-client-12:46-server-12:51
http://localhost:8894/dostuff?val=12-client-12:46-server-12:52
http://localhost:8894/dostuff?val=16-client-12:46-server-12:53
http://localhost:8894/dostuff?val=8-client-12:46-server-12:53
http://localhost:8894/dostuff?val=4-client-12:46-server-12:54
以下日誌顯示了Windows Server 2012計算機上的行爲(錯誤)。客戶端和服務器進程都在Windows Server 2012 m/c上運行。
請注意,前2個請求會同時處理,但每個後續請求需要連續5秒。
請注意,前2個請求會同時處理,但每個後續請求需要連續5秒。所有請求都是在每小時46分39秒發送的。前兩個請求的響應時間是過去一小時44分鐘46分鐘,但最後一個響應時間是48分鐘14秒。
http://localhost:8895/dostuff?val=5-client-46:39-server-46:44
http://localhost:8895/dostuff?val=1-client-46:39-server-46:44
http://localhost:8895/dostuff?val=2-client-46:39-server-46:49
http://localhost:8895/dostuff?val=6-client-46:39-server-46:54
http://localhost:8895/dostuff?val=3-client-46:39-server-46:59
http://localhost:8895/dostuff?val=4-client-46:39-server-47:4
http://localhost:8895/dostuff?val=7-client-46:39-server-47:9
http://localhost:8895/dostuff?val=9-client-46:39-server-47:14
http://localhost:8895/dostuff?val=8-client-46:39-server-47:19
http://localhost:8895/dostuff?val=10-client-46:39-server-47:24
http://localhost:8895/dostuff?val=11-client-46:39-server-47:29
http://localhost:8895/dostuff?val=12-client-46:39-server-47:34
http://localhost:8895/dostuff?val=13-client-46:39-server-47:39
http://localhost:8895/dostuff?val=14-client-46:39-server-47:44
http://localhost:8895/dostuff?val=15-client-46:39-server-47:49
http://localhost:8895/dostuff?val=16-client-46:39-server-47:54
http://localhost:8895/dostuff?val=18-client-46:39-server-47:59
http://localhost:8895/dostuff?val=17-client-46:39-server-48:4
http://localhost:8895/dostuff?val=19-client-46:39-server-48:9
http://localhost:8895/dostuff?val=0-client-46:39-server-48:14
下面的代碼可能會提供一些線索,但我懷疑它更可能是服務器上的一些配額或限制問題。
// SERVER build with "csc program.cs" run as program.exe
using System;
using System.Net;
using System.Text;
using System.Threading;
class Program
{
static void Main(string[] args)
{
HttpListener listenerLocal = new HttpListener();
listenerLocal.Prefixes.Add("http://*:8895/");
listenerLocal.Start();
while (true)
{
//var result = listener.BeginGetContext(RequestCallback, listener);
var resultLocal = listenerLocal.BeginGetContext((result) =>
{
HttpListener listener = (HttpListener)result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
Thread.Sleep(5000);
byte[] buffer = Encoding.UTF8.GetBytes(
context.Request.Url.OriginalString + string.Format(
"-server-{0}:{1}", DateTime.Now.Minute, DateTime.Now.Second));
context.Response.ContentLength64 = buffer.Length;
System.IO.Stream output = context.Response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
, listenerLocal);
resultLocal.AsyncWaitHandle.WaitOne();
}
}
}
// CLIENT build with "csc program.cs" run as program.exe
using System;
class Program
{
static void Main(string[] args)
{
for (int ii = 0; ii < 20; ii++)
{
var thr = new System.Threading.Thread((ctr) =>
{
var data = new System.Net.WebClient().OpenRead(
string.Format("http://localhost:8895/dostuff?val={0}-client-{1}:{2}"
,ctr, DateTime.Now.Minute, DateTime.Now.Second));
var reader = new System.IO.StreamReader(data);
Console.WriteLine(reader.ReadToEnd());
data.Close();
reader.Close();
});
thr.Start(ii);
}
Console.ReadLine();
}
}