2016-04-29 115 views
2

我使用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(); 
    } 

} 

回答

1

ThreadPool是不是最好的突發任務,而不是您可以使用純Thread

使用此爲您的服務器

using System; 
using System.Text; 
using System.Net; 
using System.Threading; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     HttpListener listenerLocal = new HttpListener(); 
     listenerLocal.Prefixes.Add("http://*:8895/"); 
     listenerLocal.Start();  

     int count = 0; 
     while (true) 
     { 
      if (count == 20) 
       continue; 

      Interlocked.Increment(ref count); 

      var thr = new Thread(ctr => 
      { 
       var l = ctr as HttpListener; 
       HttpListenerContext context = l.GetContext(); 

       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(); 

       Interlocked.Decrement(ref count); 
      }); 
      thr.Start(listenerLocal); 
     } 
    } 
}