缩放 ASP.NET SignalR 峰值性能应用

 

介绍

ASP.NET 是一个非常流行的用于开发实时 Web 应用程序的平台,因为它为开发人员提供了一组丰富的开发辅助功能。 SignalR 就是其中一项功能,它可以帮助您高效地开发实时数据处理 ASP.NET 应用程序。

SignalR(“R”代表实时)是一个著名的 ASP.NET Web 开发人员开源库,它允许您在信息可用时将内容从服务器端推送到所有连接的客户端。 这有助于简化向应用程序添加实时 Web 功能所需的开发工作。

 

为什么要使用 ASP.NET SignalR?

SignalR 使您能够在 ASP.NET 应用程序中让服务器端代码立即将内容推送到连接的瘦客户端,因为它变得可用,而不是等待客户端对新数据发出另一个请求。 客户端不再需要依赖典型的 HTTP 轮询机制,相反,SignalR 使用推送机制将新内容提供给客户端。 这有助于提高整体应用程序性能和用户体验。

SignalR 有一个非常简单的 API,它非常易于使用,可以直接从服务器端调用客户端浏览器内的客户端 JavaScript 函数。 它使用远程过程调用 (RPC) 来调用 ClientServer 通信,并且还提供了围绕 Client-Server 连接管理的完整 .NET 代码。

SignalR 处理服务器和客户端之间的完整通信功能,您不需要自己实现。 为了进行超快速的消息交换,SignalR 内置了一个传输层。 您需要做的就是将 SignalR 资源引入您的 ASP.NET 应用程序并开始使用它的方法。

这是一个高级图表供参考。

SignalR 中方法的调用
图 1:SignalR 中方法的调用(来自 MSDN)

SignalR 在内部和后端处理所有连接,如果客户端支持(HTML5 及更高版本),则使用 Web 套接字。 如果 Web Sockets 不可用,那么它会在必要时自动回退到旧的传输机制。 这简化了您的开发工作,您不必再自己编写和管理此通信代码。

 

创建您的第一个 ASP.NET SignalR 应用领域

在您的应用程序中使用 SignalR 比您想象的要容易得多。 在这种情况下,让我们以聊天中心为例。 您可以从添加 SignalR 创建一个简单的 ASP.NET Web 项目开始。 现在,对于聊天中心程序,您可以调用包含用于与 SignalR 连接进行通信的内置方法的通用中心类。

这是您如何导入 Microsoft.AspNet.SignalR 集线器 示例程序中调用示例的类 广播消息 在所有连接的客户端上。

namespace SignalRChat
{
   public class ChatHub : Hub
   {
      public void Send(string name, string message)
      {
         // Call the broadcastMessage method to update clients.
         Clients.All.broadcastMessage(name, message);
      }
   }
}

图 2:SignalR ChatHub 类实现

以下示例定义了 JavaScript 客户端中的方法。

//Add script to update the page and send messages.
   <script type="text/javascript">
      $(function () {
         //Declare a proxy to reference the hub.
         var chat = $.connection.chatHub;
		 
         // Create a function that the hub can call to broadcast messages.
         } chat.client.broadcastMessage = function (name, message) {
         // Html encode display name and message.
         ...
         });
   </script>

图 3:JavaScript 实现

 

ASP.NET SignalR 用例

任何使用实时 Web 功能的 ASP.NET 应用程序都是将 SignalR 合并到其架构中的合适人选。 换句话说,这是一个应用程序将大量新内容从服务器推送到客户端并且用户需要在数据变化时使用它的场景。

同样,SignalR 可用于增强使用 AJAX 长轮询机制检索新数据的应用程序的性能。 因此,只要 ASP.NET 应用程序中有数据更新,SignalR 就会自动调用客户端 JavaScript 方法来请求数据。 这可确保实时更新即时发送到 Web 客户端。

下面提到了 SignalR 的一些流行用例。

  1. 聊天系统
  2. 物联网(IOT)
  3. 游戏应用
  4. 航空公司预订系统
  5. 证券交易所申请
  6. 其他更多...
 

问题:SignalR 不能开箱即用地扩展

虽然在您的 ASP.NET 应用程序中实现 SignalR 库可能是一个明智的选择,但它无法线性扩展实际上可能会破坏其整个目的。 原因如下:

由于 SignalR 正在开发基于 Web 套接字的模型,因此其单服务器部署工作正常,所有消息都发送到所有 Web 服务器连接的客户端。

但是,基于增加的应用程序请求负载,单个服务器很快就会达到容量。 此时,您需要通过添加更多 Web 服务器并创建“Web Farm”来进行扩展。 这样做时,您的客户端请求是分布式的,因此也可能会被路由到不同的 Web 服务器。 通过 Web 套接字连接到一个 Web 服务器的客户端将不会接收从另一个 Web 服务器发送的消息。 这将导致客户端不会收到 SignalR 消息并保持不同步的情况。

这些客户端实际上会等到他们各自的 Web 服务器推送该功能,这会增加延迟。 此外,在基于多服务器的应用程序中,并非所有 Web 服务器都调用传入的新数据。 因此,很有可能这些新数据根本不会被推送到相应的客户端,并且消息会完全丢失。

让我们以实时股票市场应用程序为例,每秒有数千个股票价值在变化。 在这种情况下,每次价格发生变化时,最终客户都需要准确且绝对正确的信息。

股票市场处理大量的高交易数据,将所有信息及时推送给所有用户非常重要。 拥有 Web 场可能会导致某些用户的延迟增加,并且某些用户可能会完全错过重要的更新。 这会造成糟糕的用户体验,并对您的业务产生不利影响。

为了解决这些问题,Microsoft 提供了使用背板的选项,该背板通常可以定义为中央消息存储,所有 Web 服务器都同时连接到它。

SignalR backplane 允许 Web 服务器先连接并将所有消息发送给自己,而不是发送给自己连接的客户端。 然后,背板将这些消息广播到所有实习生的 Web 服务器,将这些消息传输到其连接的客户端。 这确保了所有消息都发送到所有终端客户端,即使是由未连接客户端的 Web 服务器调用。

在基于 SignalR 的应用程序中使用背板
图 4:在基于 SignalR 的应用程序中使用背板

SignalR backplane 可以是磁盘、数据库、消息总线或内存中的分布式缓存。 让我讨论一下最常用的背板选项及其相关问题。

 

关系数据库的问题 SignalR Backplane

SignalR 用于处理大量数据的实时应用程序。 背板需要能够以快速可靠的方式管理极端的消息负载。 关系数据库通常用作背板,不太适合,因为背板本质上需要可扩展。

让我们举一个例子,您有一个 ASP.NET 电子商务应用程序,该应用程序部署在一个网络场中的 10 个 Web 服务器上。 所有这 10 个 Web 服务器都有各自的基于浏览器的客户端通过 SignalR 连接到它们,Web 服务器还连接到背板,在这种情况下,背板是一个数据库。

如果其中一个 Web 服务器生成 1 条消息,每个消息总共有 10 条消息,这 10 条消息将被传输到背板,然后数据库会将所有这些消息广播到所有连接的 10 台 Web 服务器。 数据库总共广播了多达 100 条消息。

现在想象一下相同的设置,但应用程序非常健谈,并且您的服务器在任何给定时刻总共产生 10000 条消息(每个 Web 服务器 1000 条消息)。 背板必须同时广播 100000 条消息 (10000 x 10)。 您可以看到当请求数量增加时数据库很容易阻塞。

以下是使用关系数据库时的一些问题 SignalR backplane:

  1. 通常,事务负载非常高,需要更快的交付来排除延迟因素。 关系数据库速度很慢,甚至在峰值实时数据处理负载下会阻塞。
  2. 基于磁盘,关系数据库永远无法以足够快的速度在高负载下实现所需的吞吐量。
  3. 最重要的是,关系数据库显然缺乏线性扩展能力,您无法添加更多服务器来处理更多负载。
 

问题 Redis as SignalR Backplane

第二个选项可以使用 Redis 身为你的 SignalR backplane 这虽然解决了关系数据库的性能和可伸缩性相关问题,但它也不是一个合适的选择。 以下是与此相关的一些原因:

  • Redis 是基于 Linux 的分布式缓存,不是原生 .NET 选项。 使用基于 Linux 的系统 ASP.NET SignalR 如果您必须同时拥有 Linux 堆栈和 Windows,并且需要单独的专业知识来管理和监控此设置,这并没有多大意义。
  • .NET 开发人员在开发此类实时 Web 应用程序时总是渴望 100% 本机 .Net 堆栈。 将非本地 .NET 解决方案作为 SignalR backplane 而所有其他应用程序模块都是 100% 本机 .NET。
  • 另一个限制 Redis 是它在 Microsoft Azure 平台上的 .NET windows 移植版本根据用户评论充满了错误,甚至可以避免 Redis 在 Azure 中使用他们自己的 .NET Windows 移植版本。

这使得 Redis,从兼容性的角度来看,.NET 开发人员之间的矛盾选择。

 

解决方案:使用 NCache as SignalR Backplane

NCache 是由开发的内存中分布式缓存系统 Alachisoft 并且是用作背板的最合适的选项。 NCache 是一组廉价的缓存服务器,它们汇集在一起​​以提供可扩展的内存和 CPU 容量。 它本质上是多个服务器的逻辑容量,具有用作 SignalR backplane.

关于使用的最好的部分 NCache 身为你的 SignalR backplane 是它是百分之百的原生 .NET,并且您不需要在 ASP.NET 应用程序中进行任何重大的代码更改。 它就像一个即插即用选项,不仅让您能够管理背板消息,而且您还可以使用 NCache 性能监控工具。

NCache 提供 SignalR 扩展,用作 ASP.NET 应用程序中的背板。

您在网络场中的所有网络服务器都已注册 NCache 运用 NCache Pub/Sub 消息传递平台。 您的 Web 服务器为 SignalR 消息注册一个特定的主题,并且 NCache 然后将这些消息广播到所有 Web 服务器。 它基本上是一种双向消息传输结构,您的发布者可以是订阅者,反之亦然。

运用 NCache 作为一个 SignalR Backplane
图 5:使用 NCache 作为一个 SignalR Backplane

插上 NCache 作为基于 SignalR 的应用程序中的背板,您只需要引入一行代码,这在分步实施指南中有所提及。

 

为什么 NCache 背板比 SQL Server 更好?

为了在您的 ASP.NET 应用程序中获得最佳用户体验, NCache 作为一个非常快速、可靠和可扩展的背板来处理大量的通知。 下面提到的是使用的一些主要优点 NCache 而不是 RDBMs 作为背板。

  1. NCache 可线性扩展(高吞吐量和低延迟)

    最重要的特点 NCache 背板是它提供最大的吞吐量和最小的延迟。 它通过将所有消息处理保留在内存中,以快速的方式无缝处理大量数据,排除任何延迟增加的可能性。

    为了及时传递所有信息, NCache 通过在缓存集群中的所有可用服务器上分配负载,在传输期间提供最大吞吐量,并且它还允许您在运行时添加更多服务器。

    以下是一些性能基准数字供参考。

    性能数字 NCache
    图 6:性能数据 NCache

    这为您提供了应用程序架构内的整体线性可扩展性,您不必担心应用程序性能下降,特别是在极端负载下。

  2. NCache 非常可靠

    第二个特点 NCache 背板是其极高的可靠性。 为了确保有保证的消息传递,尤其是在任务关键型应用程序的情况下, NCache 可以用作背板,因此您不必担心由于服务器停机或因维护而停机而丢失任何消息。 它保留集群中使用的每个缓存服务器的备份 SignalR backplane 如果服务器出现故障,它会自动可用。

    极高的可靠性 NCache 归因于其将所有消息广播到连接到背板的每个 Web 服务器的特性。 在其他服务器上备份您的数据可确保在您的任务关键型应用程序传输大量负载时,不会有数据丢失的机会。

  3. NCache 高度可用

    另一个重要特征 NCache 背板是它的高可用性。 和 NCache 安装为您的 SignalR backplane,您的系统变得高度可用,因为您的消息现在正在通过始终处于活动状态的缓存集群传输。

    NCache 体系结构通过其“始终活动的缓存集群”确保高可用性功能,该集群可以基于我们的各种缓存拓扑之一。 例如,“分区-副本”拓扑为您提供所有服务器上的活动分区,并且每个服务器都有它的备份。 因此,如果服务器出现故障,客户端会自动检测到该情况并将其连接故障转移到其他幸存节点。

    缓存集群 NCache 即使只有 1 台服务器启动并正常工作,它也能正常工作,这就是您至少需要 XNUMX% 正常运行时间的情况。 如果您的服务器遭受自然灾害或您出于维护目的而故意将其关闭,则此功能会带来回报。 简而言之,实用的缓存拓扑 NCache 帮助您在基于 SignalR 的应用程序中实现 100% 的正常运行时间。

    分区副本缓存拓扑
    图 7:分区副本缓存拓扑
 

为什么 NCache 优于 Redis?

NCache 也比 Redis 从功能的角度。 排除开发者面临的所有缺点 Redis 分布式缓存系统, NCache 具有这三个最高级的特征。

  • 本机 .NET: NCache 是 100% 本机 .NET,因此它非常适合使用 SignalR 的 ASP.NET 应用程序。 另一方面, Redis 来自 Linux 背景,不是原生 .NET 缓存。
  • 比...快 Redis: NCache 实际上比...更快 Redis. NCache 客户端缓存功能提供 NCache 显着的性能提升。
  • 更多功能: NCache 提供了许多非常重要的分布式缓存功能, Redis 才不是。 在此查看更多详细信息 Redis vs NCache
 

实现 NCache SignalR Backplane

你可以部署 NCache 身为你的 SignalR Backplane 只需进行一行更改,您就可以按照以下分步教程为您的应用程序配备此功能。

  1. 安装 NuGet 包

    从安装开始 Alachisoft.NCache.SignalR 通过在包管理器控制台中执行以下命令,将 NuGet 包打包到您的应用程序:

    Install-Package Alachisoft.NCache.SignalR
  2. 包括命名空间

    在您的 启动文件 文件,包括这两个命名空间,如下所述:

    • Alachisoft.NCache.SignalR
    • 微软.AspNet.SignalR
  3. 修改 Web.config

    在您的 Web.config 文件中,您必须定义 cacheName 和 事件键 ,在 标签:

    <configuration>
       <appSettings>
          <add key="cache" value="myPartitionedCache"/>
          <add key="eventKey" value="Chat"/>
       </appSettings>
    </configuration>

    图 8:Web.config 更改

  4. 注册 NCache as SignalR Backplane 为您的应用程序

    注册一个使用实例NCache() 方法在您的应用程序的 Startup.cs 中具有以下任一重载:

    过载 1:
    public static IDependencyResolver
    	UseNCache(this IDependencyResolver resolver, string cacheName, string eventKey);
    public class Startup
    {
     	public void Configuration(IAppBuilder app)
    	{
    		string cache, eventKey;
    		cache = ConfigurationManager.AppSettings["cache"];
    		eventKey = ConfigurationManager.AppSettings["eventKey"];
    		//using NCache SignalR
    		GlobalHost.DependencyResolver.UseNCache(cache, eventKey);
    		app.MapSignalR();
    	}
    }
    

    图 9:注册 NCache SignalR Backplane (过载 1)

    过载 2:
    public static IDependencyResolver
    UseNCache(this IDependencyResolver resolver, NCacheScaleoutConfiguration configuration);
    
    public class Startup
    {
    	public void Configuration(IAppBuilder app)
    	{
    		string cache, eventKey;
    		cache = ConfigurationManager.AppSettings["cache"];
    		eventKey = ConfigurationManager.AppSettings["eventKey"];
    		NCacheScaleoutConfiguration configuration = new NCacheScaleoutConfiguration(cache, eventKey);
    		//using NCache SignalR
    		GlobalHost.DependencyResolver.UseNCache(configuration);
    		app.MapSignalR();
    	}
     ...

    图 10:注册 NCache SignalR Backplane (过载 2)

 

结论

总结一下, NCache 本质上是一个基于 .NET 的内存分布式缓存,可用于所有实时 ASP.NET Web 应用程序,作为 SignalR 的背板,以提高 Web 应用程序的性能。

使其与其他可用选项区分开来的功能包括其超快速性能、100% 正常运行时间、数据可靠性、有保证的消息传递以及以最小延迟保持最大吞吐量的能力。

接下来做什么?

联系我们

联系电话
©版权所有 Alachisoft 2002 - 版权所有。 NCache 是 Diyatech Corp. 的注册商标。