【问题标题】:SignalR hub scalability issueSignalR 集线器可扩展性问题
【发布时间】:2012-07-23 17:09:23
【问题描述】:

我们有一个名为 StatusUpdateHub 的 SignalR 集线器。此集线器由名为 HubClient 的 .NET 客户端更新。该客户端将(在生产中)被多个用户每秒调用大约 1000 次,用于不同的事务。这是客户端代码:

public static class HubClient
{
    private static readonly string statusUpdateUrl = ConfigurationManager.AppSettings["StatusUpdateUrl"];
    private static readonly HubConnection connection = new HubConnection(statusUpdateUrl);
    private static readonly IHubProxy hub = connection.CreateProxy("StatusUpdateHub");

    internal static void UpdateBrowser(long transactionId)
    {
        connection.Start().ContinueWith(task => hub.Invoke("UpdateTransactionStatus", transactionId)).ContinueWith(task =>
        {
            if (task.IsFaulted && task.Exception != null)
            {
                // log error
            }
        });
    }
}

当使用 100 个并发用户调用此代码时,它工作正常,但是当我们将并发用户数增加到 250 时,我们会看到以下错误:

UpdateBrowser 中出现意外错误:System.InvalidOperationException: 连接尚未建立。在 SignalR.Client.Connection.SignalR.Client.IConnection.Send[T](字符串 数据)在 SignalR.Client.Hubs.HubProxy.Invoke[T](字符串方法, SignalR.Client.Hubs.HubProxy.Invoke(String) 处的 Object[] args) 方法,对象 [] 参数)在 Application.Services.HubClient.c_DisplayClass2.b_0(任务 task1) 在 c:\Build\Work\Application\Services\HubClient.cs:line 20
在 System.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj)
在 System.Threading.Tasks.Task.Execute()

让我们知道如何使代码更具可扩展性?

【问题讨论】:

  • 您是否对服务器上的同时连接有任何限制?
  • 您是否也在整个运行过程中监控内存消耗?你是。我很想知道随着连接/断开连接的用户数量的增加,您看到的趋势是什么。我在我们的应用程序中看到了一些未释放的内存,我想知道这是由于 SignalR 还是其他原因。
  • @Stilgar 我们没有设置任何限制。我应该在 machine.config 中更改什么设置?
  • @ElHaix 会要求我的性能测试团队向我提供统计数据并通知您。
  • github.com/SignalR/SignalR/wiki/Performance - 默认值很高,所以我怀疑这是问题所在

标签: .net signalr signalr-hub


【解决方案1】:

如果这是每秒调用 1000 次的方法,那么您不应该每次都调用 connection.Start()。

只打开一次连接,然后调用它的方法。

编辑,我的意思是,至少,让你的代码做这样的事情:

internal static void UpdateBrowser(long transactionId)
{
    lock (connection) 
    {
        if (connection.State == ConnectionState.Disconnected){
            connection.Start().Wait();
        }
    }
    hub.Invoke("UpdateTransactionStatus", transactionId).ContinueWith(task =>
    {
        if (task.IsFaulted && task.Exception != null)
        {
            // log error
        }
    });
}

【讨论】:

    【解决方案2】:

    默认情况下,.NET 允许从客户端应用程序传出 2 个并发连接,从 ASP.NET 应用程序传出 10 个并发连接。如果您想增加此数字,请将http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx 设置为更大的数字。看看有没有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-19
      • 1970-01-01
      • 2018-11-04
      • 2017-06-17
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多