HTTP。SYS 強制中斷連線的 WCF 自主裝載服務的 HTTP 繫結

請注意--重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,且可能由 Microsoft Community 利用 Community Translation Framework技術或人工進行事後編修。翻譯過程並無專業譯者參與。Microsoft 同時提供使用者人為翻譯、機器翻譯及社群編修後的機器翻譯三種版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,所有翻譯文章都可能不盡完美,內容都可能出現詞彙、語意或文法上的錯誤。就翻譯內容之不正確或錯誤,或客戶因使用翻譯內容所產生的任何損害,微軟不負擔任何責任。Microsoft將依合理的商業努力不斷地更新機器翻譯軟體和工具,以期能為使用者提供更好的服務。

按一下這裡查看此文章的英文版本:3137046
徵狀
在執行 Windows Server 2012 R2,並使用 HTTP 基礎 (例如basicHttpBinding) 的繫結伺服器上自行主控的 Windows 通訊基礎 (WCF) 服務,伺服器間歇地卸除基礎的 TCP 連線。發生這個問題時,您可以在 HTTP 看到它。SYS 通常位於 C:\WINDOWS\System32\LogFiles\HTTPERR 資料夾中的記錄檔。記錄檔應該有一個 cites Timer_MinBytesPerSecond做的理由的項目。Windows Server 2008 R2 中沒有發生這個問題。

記錄檔項目類似下列 ︰
#Fields ︰ 日期時間 c ip c 連接埠 s ip s 連接埠 cs 版本 cs 方法 cs uri sc 狀態 s 網站識別碼的原因 s-queuename
日期時間 10.145.136.58 41079 10.171.70.136 8888 HTTP/1.1 張貼 /MySelfHostedService/TestService1-Timer_MinBytesPerSecond-
日期時間 10.145.136.58 41106 10.171.70.136 8888 HTTP/1.1 張貼 /MySelfHostedService/TestService1-Timer_MinBytesPerSecond-
日期時間 10.145.136.58 40995 10.171.70.136 8888 HTTP/1.1 張貼 /MySelfHostedService/TestService1-Timer_MinBytesPerSecond-
日期時間 10.145.136.58 41022 10.171.70.136 8888 HTTP/1.1 張貼 /MySelfHostedService/TestService1-Timer_MinBytesPerSecond-
在 WCF 追蹤中,「 服務 」 無法接收位元組作業期間使用System.Net.HttpListenerException,如下列範例所示 ︰
<Exception>
<ExceptionType>System.ServiceModel.CommunicationException,System.ServiceModel,版本 = 4.0.0.0,文化特性 = 中性,PublicKeyToken = b77a5c561934e089</ExceptionType>
<Message>嘗試在不存在的網路連線上執行作業</Message>
<StackTrace>
在 System.ServiceModel.Channels.HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream.Close()
在 System.ServiceModel.Channels.HttpOutput.Close()
在 System.ServiceModel.Channels.HttpRequestContext.OnReply (訊息的訊息,TimeSpan 逾時)
在 System.ServiceModel.Channels.RequestContextBase.Reply (訊息的訊息,TimeSpan 逾時)
在 System.ServiceModel.Channels.HttpRequestContext.SendResponseAndClose (HttpStatusCode statusCode,字串 statusDescription)
在 System.ServiceModel.Channels.HttpChannelListener'1.HandleProcessInboundException (ex HttpRequestContext 內容的例外狀況)
</StackTrace>
<ExceptionString>System.ServiceModel.CommunicationException ︰ 嘗試執行作業上不存在的網路連線---&gt; System.Net.HttpListenerException ︰ 嘗試在不存在的網路連線上執行作業
在 (布林處置) 的 System.Net.HttpResponseStream.Dispose
在 System.IO.Stream.Close()
在 System.ServiceModel.Channels.HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream.Close()
---結尾的內部例外狀況堆疊追蹤---
在 System.ServiceModel.Channels.HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream.Close()
在 System.ServiceModel.Channels.HttpOutput.Close()
在 System.ServiceModel.Channels.HttpRequestContext.OnReply (訊息的訊息,TimeSpan 逾時)
在 System.ServiceModel.Channels.RequestContextBase.Reply (訊息的訊息,TimeSpan 逾時)
在 System.ServiceModel.Channels.HttpRequestContext.SendResponseAndClose (HttpStatusCode statusCode,字串 statusDescription)
在 System.ServiceModel.Channels.HttpChannelListener'1.HandleProcessInboundException (ex HttpRequestContext 內容的例外狀況)</ExceptionString>
<InnerException>
<Exception>
<ExceptionType>System.Net.HttpListenerException,系統中,版本 = 4.0.0.0,文化特性 = 中性,PublicKeyToken = b77a5c561934e089</ExceptionType>
<Message>嘗試在不存在的網路連線上執行作業</Message>
<StackTrace>
在 (布林處置) 的 System.Net.HttpResponseStream.Dispose
在 System.IO.Stream.Close()
在 System.ServiceModel.Channels.HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream.Close()
</StackTrace>
<ExceptionString>System.Net.HttpListenerException [(0x80004005) 中 ︰ 嘗試執行作業不存在的網路連線
在 (布林處置) 的 System.Net.HttpResponseStream.Dispose
在 System.IO.Stream.Close()
在 System.ServiceModel.Channels.HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream.Close()</ExceptionString>
<NativeErrorCode>4 的 CD</NativeErrorCode>
</Exception>
</InnerException>
</Exception>
發生的原因
起始 Windows Server 2012 R2 值,用來處理 HTTP 要求 (http.sys) 的核心驅動程式已變更方面如何處理Timer_MinBytesPerSecond屬性。根據預設,Http.sys 會考慮任何小於潛在的低速連線攻擊,為每秒 150 個位元組的速度射,而降到 TCP 連線釋放資源。這個問題 Windows Server 2008 R2 中沒有發生,因為在 Windows Server 2012 R2 慢速連線的閾值是限制更加嚴苛。
其他可行方案
若要解決這項功能,請將minSendBytesPerSecond設定0xffffffff 之間的值 (最大的 32 位元不帶正負號的整數值),也就是十進位 4294967295。這個特定的值會停用較低的速度速率連線功能。

您可以使用下列方法之一來將minSendBytesPerSecond設定為值0xFFFFFFFF

方法 1 ︰ 使用組態檔

 <system.net>    <settings>       <httpListener>           <timeouts minSendBytesPerSecond="4294967295" />       </httpListener>    </settings> </system.net>

方法 2 ︰ 以程式設計方式設定

變更的屬性明確的程式碼,如下列範例所示 ︰

System.Net.HttpListenerTimeoutManager.MinSendBytesPerSecond = 4294967295

如果程式碼變更服務中的沒有的選項,可以進行程式設計的選項到自訂的 serviceBehavior。也就是 「 表現方式可以與現有服務整合,藉由卸除 DLL,並變更設定,如下列範例所示 ︰
  1. 在 Visual Studio 中,開啟您的方案,並加入新的類別庫專案。其命名為"BehaviorProject"。
  2. 建立一個名為"HttpListenerBehavior"。
  3. 更新下列原始程式碼 ︰
    namespace BehaviorProject{    public class HttpListenerBehavior : BehaviorExtensionElement, IServiceBehavior    {        public override Type BehaviorType        {            get { return this.GetType(); }        }        protected override object CreateBehavior()        {            return new HttpListenerBehavior();        }        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)        {            return;        }        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)        {                        UpdateSystemNetConfiguration();        }        private void UpdateSystemNetConfiguration()        {            ConfigurationProperty minSendBytesPerSecond;            minSendBytesPerSecond = new ConfigurationProperty("minSendBytesPerSecond",                typeof(long), (long)uint.MaxValue, null, null, ConfigurationPropertyOptions.None);            ConfigurationPropertyCollection properties;            HttpListenerTimeoutsElement timeOuts = new HttpListenerTimeoutsElement();            properties = GetMember(timeOuts, "properties") as ConfigurationPropertyCollection;            if (properties != null)            {                properties.Remove("minSendBytesPerSecond");                SetMember(timeOuts, "minSendBytesPerSecond", minSendBytesPerSecond);                properties.Add(minSendBytesPerSecond);            }        }        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)        {            return;        }        public static object GetMember(object Source, string Field)        {            string[] fields = Field.Split('.');            object curr = Source;            BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;            bool succeeded = false;            foreach (string field in fields)            {                Type t = curr.GetType();                succeeded = false;                FieldInfo fInfo = t.GetField(field, bindingFlags);                if (fInfo != null)                {                    curr = fInfo.GetValue(curr);                    succeeded = true;                    continue;                }                PropertyInfo pInfo = t.GetProperty(field, bindingFlags);                if (pInfo != null)                {                    curr = pInfo.GetValue(curr, null);                    succeeded = true;                    continue;                }                throw new System.IndexOutOfRangeException();            }            if (succeeded) return curr;            throw new System.ArgumentNullException();        }        public static void SetMember(object Source, string Field, object Value)        {            string[] fields = Field.Split('.');            object curr = Source;            BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;            bool succeeded = false;            int i = 0;            foreach (string field in fields)            {                i++;                Type t = curr.GetType();                succeeded = false;                FieldInfo fInfo = t.GetField(field, bindingFlags);                if (fInfo != null)                {                    if (i == fields.Length)                        fInfo.SetValue(curr, Value);                    curr = fInfo.GetValue(curr);                    succeeded = true;                    continue;                }                PropertyInfo pInfo = t.GetProperty(field, bindingFlags);                if (pInfo != null)                {                    if (i == fields.Length)                        fInfo.SetValue(curr, Value);                    curr = pInfo.GetValue(curr, null);                    succeeded = true;                    continue;                }                throw new System.IndexOutOfRangeException();            }            if (succeeded) return;            throw new System.ArgumentNullException();        }    }}

  4. 建置程式庫應用程式。
  5. 將所產生之 DLL 複製到您的應用程式資料夾中。
  6. 開啟應用程式組態檔中,找出<system.serviceModel>標記,並將下列的自訂行為 ︰</system.serviceModel>
    <extensions> <behaviorExtensions> <add name="httpListenerBehavior" type="BehaviorProject.HttpListenerBehavior, BehaviorProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> </behaviorExtensions></extensions><behaviors> <serviceBehaviors> <!-- if the serviceBehavior used by the service is named, add to the appropriate named behavior --> <behavior name="customBehavior"> <!-- The behavior is referenced by the following in line. Visual Studio will mark this line with a red underline because it is not in the config schema. It can be ignored. Notice that the other behaviors (like serviceMetadata) does not need to be added if they are not currently present --> <httpListenerBehavior /> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors></behaviors>
其他相關資訊
如果要判斷所做的變更是否已有效,請使用下列方法之一。

方法 1

  1. 擷取開啟 serviceHost 時的記憶體傾印 fileafter。
  2. 傾印的物件型別System.Net.HttpListenerTimeoutManager,並讀取minSendBytesPerSecond屬性。
0:000 > !DumpObj /d 02694a64
名稱 ︰ System.Net.HttpListenerTimeoutManager
MethodTable: 7308b070
EEClass: 72ec5238
大小 ︰ 20(0x14) 位元組
檔案 ︰ C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
欄位 ︰
細明體欄位位移類型 VT 屬性值的名稱
73092254 4001605 4...Net.HttpListener 0 執行個體 026932f0 接聽程式
73c755d4 4001606 8 System.Int32 [0] 執行個體 02694a78 逾時
73c7ef20 4001607 c System.UInt32 1 執行個體 4294967295 minSendBytesPerSecond<>

請注意, minSendBytesPerSecond的值 4294967295。

方法 2
  1. 在管理員模式中,開啟 cmd.exe,並從命令提示字元執行下列命令,(之後會開啟 serviceHost) ︰

    netsh http 顯示 servicestate 檢視 = 「 工作階段 」 > %temp%\netshOutput.txt
  2. 執行下列命令以開啟 netshOutput.txt 檔案。它會在記事本中開啟。

    開始 %temp%\netshOutput.txt
  3. 搜尋 (例如 8888) 的服務應用程式連接埠編號,檢視您的工作階段屬性。這是步驟,以確認 [最小的傳送速率 (位元組/秒) 會覆寫以4294967295的值。
  4. 您應該會看到類似下列的項目 ︰

    伺服器工作階段識別碼 ︰ FE00000320000021
    版本 ︰ 2.0
    狀態 ︰ 作用中
    內容 ︰
    最大頻寬 ︰ 4294967295
    逾時 ︰
    實體主體逾時 (秒) ︰ 120
    清空實體主體逾時 (秒) ︰ 120
    要求佇列逾時 (秒) ︰ 120
    閒置連線逾時 (秒) ︰ 120
    標頭等候逾時 (秒) ︰ 120
    最小傳送速率 (位元組/秒) ︰ 150
    URL 群組 ︰
    URL 群組識別碼 ︰ FD00000340000001
    狀態 ︰ 作用中
    要求佇列名稱 ︰ 佇列未命名的要求。
    內容 ︰
    最大頻寬 ︰ 繼承
    最大連線數 ︰ 繼承
    逾時 ︰
    實體主體逾時 (秒) ︰ 0
    清空實體主體逾時 (秒) ︰ 0
    要求佇列逾時 (秒) ︰ 0
    閒置連線逾時 (秒) ︰ 0
    標頭等候逾時 (秒) ︰ 0
    最小傳送速率 (位元組/秒) ︰ 4294967295<>
    已註冊的 Url 數目 ︰ 1
    已註冊的 Url:
    HTTP://+:8888/TESTSERVICE1/
如需詳細資訊,請參閱 HttpListenerTimeoutManager.MinSendBytesPerSecond 屬性 在 Microsoft 開發人員網路網站上的主題。
注意 :本文屬於「快速發佈」文章,係由 Microsoft 技術支援或組織內部直接建立。 本文所包含的資訊是為了回應新問題而依現況提供。 因此為了迅速對外發佈,文章內容可能含有印刷錯誤,而且可能會在不另行通知的情況下進行修改。 如需其他考量事項,請參閱使用規定

警告:本文為自動翻譯

內容

文章識別碼:3137046 - 最後檢閱時間:03/24/2016 22:21:00 - 修訂: 3.0

Windows Communication Foundation 4.5, Windows Communication Foundation 4

  • kbmt KB3137046 KbMtzh
意見反應