【问题标题】:SignalR seems to be slowing startup of my MVC / Azure applicationSignalR 似乎正在减慢我的 MVC / Azure 应用程序的启动速度
【发布时间】:2024-01-07 20:49:01
【问题描述】:

我有一个在 .NET 4.5 下在 Windows Azure 上的 WebRole 上运行的 MVC 应用程序,使用 SignalR 1.0 -alpha2,并使用 ServiceBus 背板。在我的 App_Start 文件夹中,我有 RegisterHubs.cs,如下所示:

[assembly: PreApplicationStartMethod(typeof(pageengine.studio.RegisterHubs), "Start")]

namespace pageengine.studio
{
    public static class RegisterHubs
    {
        public static void Start()
        {
            // Register the default hubs route: ~/signalr/hubs
            RouteTable.Routes.MapHubs();
        }
    }
}

在 Global.asax 中,我有以下内容:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    String connectionString = "Endpoint=sb://MYNAMESPACE.servicebus.windows.net/;SharedSecretIssuer=MY_ISSUER;SharedSecretValue=MY_SECRET_VALUE";
    GlobalHost.DependencyResolver.UseWindowsAzureServiceBus(connectionString, 1);
}

我已经按上述方式运行测试(称为 MVC + SignalR + ServiceBus),Global.asax 中的 GlobalHost.DependencyResolver ... 行已被注释掉(MVC + SignalR),[assembly: PreApplicationStartMethod ...RouteTable.Routes.MapHubs(); 两行也已注释掉注释掉(仅 MVC)。

在开始之前,我使用 Start without Debugging(并部署到 IIS Express)启动 Azure 模拟器,在每次注释/取消注释之后,我重建应用程序,然后在 Google Chrome 中进行硬重新加载。我十次测试的平均加载时间如下:

单独使用 MVC:1.33 秒

MVC + SignalR:31.95 秒

MVC + SignalR + ServiceBus:53.1 秒

我没有在我的实时 Azure 站点上运行相同的比较,但运行这些测试的原因是在实施 SignalR 后,它的运行速度明显变慢。

我原以为这只是因为 SignalR 处于 alpha 阶段,但其他地方的讨论 (signalR MVC site loads indefinitely after signalR install) 表明这不应该是这样。我不确定上面的实现是否有问题,或者这是 Azure 特有的问题,还是其他问题。

还有其他人遇到过类似的性能问题吗?我上面的代码有什么问题吗?有没有人有任何潜在的补救措施?

更新

我在 WebRole 的 Start 和 Run 方法、RegisterHubs 方法的开头和结尾以及 Application_Start 方法的开头和结尾添加了一条跟踪语句,并注释掉了 ServiceBus 代码,所以我只是在测试 MVC + SignalR。

再次,经过多次测试,结果是一致的:

Web 角色开始时间:20:55:17

网络角色运行:20:55:17

RegisterHubs 开始时间:20:55:28

RegisterHubs 开始时间:20:56:10 // 42 秒。平均值接近 45。

Application_Start In:20:56:14

Application_Start 开始时间:20:56:21

作为参考,我的 RegisterHubs 方法现在如下所示:

public static void Start()
{
    System.Diagnostics.Debug.WriteLine("RegisterHubs Start In: " + DateTime.Now.ToLongTimeString());
    // Register the default hubs route: ~/signalr/hubs
    RouteTable.Routes.MapHubs();
    System.Diagnostics.Debug.WriteLine("RegisterHubs Start Out: " + DateTime.Now.ToLongTimeString());
}

进一步更新

问题出在(讽刺的是)PerformaceCounterManager 类,Microsoft.AspNet.SignalR.Core 程序集中。

函数SetCounterProperties() 在23 个不同_counterProperties 的循环上调用LoadCounter。这些调用中的每一个都失败并处理异常,导致返回_noOpCounter,但是失败需要一到两秒的时间,并且这会累积到四十秒的延迟(所有这些时间都在调试器打开时 -当然,没有它会更快,但仍然明显滞后)。

这里是处理的异常的跟踪,以防有用:

A first chance exception of type 'System.InvalidOperationException' occurred in System.dll InvalidOperation: SignalR - Errors: Hub Invocation Total - deployment18(966).Azure.Studio_IN_0_Web - System.InvalidOperationException: Cannot load Counter Name data because an invalid index '' was read from the registry. at System.Diagnostics.PerformanceCounterLib.GetStringTable(Boolean isHelp) at System.Diagnostics.PerformanceCounterLib.get_NameTable() at System.Diagnostics.PerformanceCounterLib.get_CategoryTable() at System.Diagnostics.PerformanceCounterLib.CategoryExists(String category) at System.Diagnostics.PerformanceCounterLib.CategoryExists(String machine, String category) at System.Diagnostics.PerformanceCounterCategory.Exists(String categoryName, String machineName) at System.Diagnostics.PerformanceCounterCategory.Exists(String categoryName) at Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.LoadCounter(String categoryName, String counterName, String instanceName) in d:\Work\CLIENTS\PageEngine\Resources\SignalR-master\src\Microsoft.AspNet.SignalR.Core\Infrastructure\PerformanceCounterManager.cs:line 275

我能找到的最简单的解决方法是没有 PerformanceCounters。 目前我已将GetPropertyInfo() 修改为简单地返回new PropertyInfo[0]我已将LoadCounter 修改为始终返回_noOpCounter。启动时间现在约为 5 秒,使用服务总线则为 10 秒。

【问题讨论】:

  • 第二个没有意义。没有服务总线的单一角色的 MVC + SignalR + azure 不应该减慢任何速度。启动服务总线是有意义的,因为它必须创建主题和订阅。
  • @dfowler 是的,我对 ServiceBus 时间并不感到惊讶,但其他结果绝对一致。我将尝试对各种调用进行一些跟踪,看看是否能识别出瓶颈。
  • @dfowler 已更新 - 见上文。 MapHubs() 调用肯定会浪费时间。不知道为什么。我可以做些什么来进一步调查?今晚完成,但明天(英国时间)会再看一遍。
  • 获取源代码并开始调试:)。您可以在 jabbr 中 ping 我以获取更多详细信息。
  • @dfowler - 请参阅上面的更新。问题在于LoadCounter 中的PerformaceCounterManager

标签: asp.net-mvc performance azure signalr


【解决方案1】:

这是 SignalR 1-alpha2 中的一个错误,现已在 github 上报告:https://github.com/SignalR/SignalR/issues/1063

更新

...现在已修复:https://github.com/SignalR/SignalR/commit/fda3aa41a9250a072e8487882ae806ffe547f2bb

【讨论】: