簡體   English   中英

WCF可靠消息:maxPendingChannels增加后的口吃服務

[英]WCF Reliable Messaging: stuttering service after maxPendingChannels increase

我們有一個問題,即在負載測試期間,如果我們在我們的某個服務中快速撥打電話,我們就會收到錯誤

“System.ServiceModel.ServerTooBusyException:RM Destination拒絕了創建可靠會話的請求。服務器'net.tcp:// localhost:10511 / ParameterMonitorService'太忙,無法處理此請求。請稍后再試。不能打開。”

我們將maxPendingChannels的值從其默認值4增加到128然后超出,並且錯誤已經消失,但是現在,不是拋出異常,服務將停止處理負載下的消息,然后在幾分鍾后再次開始。

它似乎沒有掉落任何東西,只是掛了一會兒。 我們對服務的攻擊越多,這種恢復似乎就越長。

該服務配置為Per-Call with ConcurrencyMode Multiple。 其他行為設置是:

<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" maxConcurrentInstances="100"/>

<customBinding>

    <binding name="Services_Custom_Binding" openTimeout="00:00:20" sendTimeout="00:01:00">          
        <reliableSession  ordered="true" inactivityTimeout="00:10:00" maxPendingChannels="128" flowControlEnabled="true" />
        <binaryMessageEncoding>
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />            
        </binaryMessageEncoding>
        <tcpTransport maxPendingConnections="100" listenBacklog="100" />          
      </binding>
  </customBinding>

我們有點卡住了。 任何幫助贊賞!

這是一個經典的性能調優故事。 通過在可靠會話上重新配置限制,您已經刪除了曾經是系統中的瓶頸,並將瓶頸移到了系統中的其他位置。

你真的不能指望人們在沒有任何關於你的服務托管方式,硬件,它在做什么或者如何做到這一點的情況下,毫無疑問地了解瓶頸所在的地方。 您需要使用Windows性能監視器計數器全面檢測系統,並解釋這些以了解系統中現在發生的資源爭用。

我的第一個猜測是,在刪除會話限制后增加的並發性導致了托管線程池線程的爭用,但這只是猜測 - 實際上你想要根據證據進行診斷,而不是猜測。

默認情況下,線程池創建8個線程,之后每秒僅添加兩個線程。 當您同時啟動大量工作人員時,WCF會因為線程啟動速度不夠快而無法啟動。

這個解決方案對我很有用,無論何時你要激活很多線程,都可以調用AdjustThreads:

    Imports NLog
    Public Module AdjustThreads_

    Private _Logger As Logger = LogManager.GetCurrentClassLogger
    Private _MaxWorkers As Integer = 16
    Private _MaxCompletions As Integer = 16
    Public Sub AdjustThreads()
        Dim minworkerthreads As Integer = 0
        Dim maxworkerthreads As Integer = 0
        Dim mincompletionthreads As Integer = 0
        Dim maxcompletionthreads As Integer = 0
        Dim activeworkerthreads As Integer = 0
        Dim activecompletionthreads As Integer = 0
        Threading.ThreadPool.GetMinThreads(minworkerthreads, mincompletionthreads)
        Threading.ThreadPool.GetMaxThreads(maxworkerthreads, maxcompletionthreads)
        Threading.ThreadPool.GetAvailableThreads(activeworkerthreads, activecompletionthreads)
        Dim workers As Integer = maxworkerthreads - activeworkerthreads
        Dim completions As Integer = maxcompletionthreads - activecompletionthreads
        If workers > _MaxWorkers Then
            _MaxWorkers = _MaxWorkers
        End If
        If completions > _MaxCompletions Then
            _MaxCompletions = completions
        End If
        ' If current is (initially) 8, new threads only start twice a second.
        ' So, kick off a minimum of 16 and always increase by 50%
        Dim needworkers As Integer = _MaxWorkers * 3 \ 2
        Dim needcompletions As Integer = _MaxCompletions * 3 \ 2

        If needworkers > minworkerthreads OrElse
           needcompletions > mincompletionthreads Then
            _Logger.Info("Threadpool increasing workers to {0}, completions to {1}",
                         needworkers, needcompletions)
            Threading.ThreadPool.SetMinThreads(needworkers, needcompletions)
        End If
    End Sub
End Module

(該死的編輯器一直在使“終端模塊”脫離代碼,如果有人可以解決它?)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM