我在 Windows Azure 上的 WebRole 上运行在 .NET 4.5 下的 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),GlobalHost.DependencyResolver ...
Global.asax 中的行被注释掉了(MVC + SignalR),两行[assembly: PreApplicationStartMethod ...
也RouteTable.Routes.MapHubs();
被注释掉了(MVC Alone)。
在开始之前,我使用 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 站点在 signalR 安装后无限期加载)表明这不应该是这样。我不确定上面的实现是否有问题,或者这是 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。
应用程序_开始时间:20:56:14
Application_Start Out: 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()
调用LoadCounter
23 个不同的循环_counterProperties
。这些调用中的每一个都失败并且异常被处理,导致返回_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 秒。