3

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

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

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

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

该服务配置为具有 ConcurrencyMode Multiple 的 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>

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

4

2 回答 2

2

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

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

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

于 2011-02-22T10:50:54.707 回答
0

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

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

于 2018-05-08T10:05:10.603 回答