【问题标题】:WCF Reliable Messaging: stuttering service after maxPendingChannels increaseWCF 可靠消息传递:maxPendingChannels 增加后服务卡顿
【发布时间】:2011-02-22 02:48:29
【问题描述】:

我们有一个问题,即在负载测试期间,如果我们在其中一项服务上快速触发调用,我们会收到错误

"System.ServiceModel.ServerTooBusyException: 创建可靠会话的请求已被 RM 目标拒绝。服务器 'net.tcp://localhost:10511/ParameterMonitorService' 太忙,无法处理此请求。稍后重试. 无法打开频道。”

我们将 maxPendingChannels 的值从其默认值 4 增加到 128 甚至更大,并且错误已经消失,但是现在,服务不会抛出异常,而是停止处理负载下的消息,然后在几分钟后重新开始.

它似乎没有掉任何东西,它只是挂了一会儿。我们对服务的冲击越大,恢复所需的时间似乎就越长。

该服务被配置为具有多个并发模式的 Per-Call。其他行为设置有:

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

我们有点卡住了。任何帮助表示赞赏!

【问题讨论】:

    标签: wcf .net-4.0 ws-reliablemessaging


    【解决方案1】:

    这是一个经典的性能调优故事。通过在可靠会话上重新配置节流阀,您已经消除了系统中曾经的瓶颈,并将瓶颈移到了系统中的其他位置。

    你真的不能指望人们会凭空判断出现在的瓶颈在哪里,而不知道你的服务是如何托管的、在什么硬件上、它在做什么或者它是如何做的它。您需要使用 Windows 性能监视器计数器尽可能全面地检测您的系统,并解释这些计数器以了解系统中现在发生资源争用的位置。

    我的第一个猜测是,移除会话限制后并发性的增加会导致托管线程池线程的争用,但这只是一个猜测 - 你真的希望根据证据进行诊断,而不是猜测。

    【讨论】:

    • 这个问题在我们的任何环境中都是可重复的,包括在本地开发人员笔记本电脑上运行或在 VMware 之上运行的服务器环境。甚至在关闭可靠消息传递时也会发生这种情况:我们得到的不是可靠消息传递错误,而是更一般的 netTCP 套接字错误。我们现在正在研究 perfmon,但还没有什么明显的亮点。
    • 请用新错误的详细信息(您之前没有提到)更新您的问题,并以您最初描述的方式阐明何时出错以及何时“暂时挂起”。以及服务功能的详细信息(例如,它是否执行 IO;调用另一个服务或数据库;使用 COM 互操作;等等)。
    【解决方案2】:

    默认情况下,线程池创建 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
    

    (该死的编辑器不断使“结束模块”从代码中消失,如果有人可以修复它?)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多