繁体   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