为 ASP.NET Core SignalR 横向扩展设置 Redis 底板Set up a Redis backplane for ASP.NET Core SignalR scale-out

本文内容

作者: Andrew StantonBrady GasterTom Dykstra

本文介绍设置Redis服务器以用于向外扩展 ASP.NET Core SignalR 应用程序 SignalR特定方面。

设置 Redis 底板Set up a Redis backplane

  • 部署 Redis 服务器。

重要

对于生产用途,建议仅当 Redis 底板与 SignalR 应用在同一数据中心内运行时,才建议使用底板。否则,网络延迟会降低性能。如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。可以使用 Azure Redis 缓存服务进行开发和测试环境。

有关详细信息,请参阅以下资源:

  • 在 SignalR 应用中,安装 Microsoft.AspNetCore.SignalR.Redis NuGet 包。

  • Startup.ConfigureServices 方法中,在 AddSignalR后调用 AddRedis

  1. services.AddSignalR().AddRedis("<your_Redis_connection_string>");
  • 根据需要配置选项:

可以在连接字符串中或在ConfigurationOptions对象中设置大多数选项。在 ConfigurationOptions 中指定的选项会替代在连接字符串中设置的选项。

下面的示例演示如何在 ConfigurationOptions 对象中设置选项。此示例将添加一个通道前缀,以便多个应用可以共享同一 Redis 实例,如以下步骤中所述。

  1. services.AddSignalR()
  2. .AddRedis(connectionString, options => {
  3. options.Configuration.ChannelPrefix = "MyApp";
  4. });

在前面的代码中,options.Configuration 用连接字符串中指定的内容进行初始化。

  • 在 SignalR 应用中,安装以下 NuGet 包之一:

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis-依赖于 Stackexchange.redis Redis 采用2.X.X。建议将此包用于 ASP.NET Core 2.2 及更高版本。
    • Microsoft.AspNetCore.SignalR.Redis-依赖于 Stackexchange.redis Redis 采用2.X.X。此包不包含在 ASP.NET Core 3.0 及更高版本中。
  • Startup.ConfigureServices 方法中,调用 AddStackExchangeRedis
  1. services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");

使用 Microsoft.AspNetCore.SignalR.Redis时,请调用 AddRedis

  • 根据需要配置选项:

可以在连接字符串中或在ConfigurationOptions对象中设置大多数选项。在 ConfigurationOptions 中指定的选项会替代在连接字符串中设置的选项。

下面的示例演示如何在 ConfigurationOptions 对象中设置选项。此示例将添加一个通道前缀,以便多个应用可以共享同一 Redis 实例,如以下步骤中所述。

  1. services.AddSignalR()
  2. .AddStackExchangeRedis(connectionString, options => {
  3. options.Configuration.ChannelPrefix = "MyApp";
  4. });

使用 Microsoft.AspNetCore.SignalR.Redis时,请调用 AddRedis

在前面的代码中,options.Configuration 用连接字符串中指定的内容进行初始化。

有关 Redis 选项的信息,请参阅Stackexchange.redis Redis 文档

  • 在 SignalR 应用中,安装以下 NuGet 包:

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis
  • Startup.ConfigureServices 方法中,调用 AddStackExchangeRedis
  1. services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
  • 根据需要配置选项:

可以在连接字符串中或在ConfigurationOptions对象中设置大多数选项。在 ConfigurationOptions 中指定的选项会替代在连接字符串中设置的选项。

下面的示例演示如何在 ConfigurationOptions 对象中设置选项。此示例将添加一个通道前缀,以便多个应用可以共享同一 Redis 实例,如以下步骤中所述。

  1. services.AddSignalR()
  2. .AddStackExchangeRedis(connectionString, options => {
  3. options.Configuration.ChannelPrefix = "MyApp";
  4. });

在前面的代码中,options.Configuration 用连接字符串中指定的内容进行初始化。

有关 Redis 选项的信息,请参阅Stackexchange.redis Redis 文档

  • 如果对多个 SignalR 应用使用一个 Redis 服务器,请为每个 SignalR 应用使用不同的通道前缀。

设置通道前缀会将一个 SignalR 应用与其他使用不同通道前缀的应用隔离开来。如果未分配不同的前缀,则从一个应用发送到其所有客户端的消息将发送到使用 Redis 服务器作为底板的所有应用的所有客户端。

  • 为粘滞会话配置服务器场负载平衡软件。下面是有关如何执行此操作的一些文档示例:

Redis 服务器错误Redis server errors

当 Redis 服务器发生故障时,SignalR 会引发指示消息无法传递的异常。一些典型的异常消息:

  • 写入消息失败
  • 未能调用中心方法 "方法名称"
  • 未能连接到 Redis

SignalR 不会缓冲消息,以便在服务器重新启动时发送这些消息。Redis 服务器关闭时发送的任何消息都将丢失。

当 Redis 服务器再次可用时,SignalR 自动重新连接。

连接失败的自定义行为Custom behavior for connection failures

下面是演示如何处理 Redis 连接失败事件的示例。

  1. services.AddSignalR()
  2. .AddRedis(o =>
  3. {
  4. o.ConnectionFactory = async writer =>
  5. {
  6. var config = new ConfigurationOptions
  7. {
  8. AbortOnConnectFail = false
  9. };
  10. config.EndPoints.Add(IPAddress.Loopback, 0);
  11. config.SetDefaultPorts();
  12. var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
  13. connection.ConnectionFailed += (_, e) =>
  14. {
  15. Console.WriteLine("Connection to Redis failed.");
  16. };
  17. if (!connection.IsConnected)
  18. {
  19. Console.WriteLine("Did not connect to Redis.");
  20. }
  21. return connection;
  22. };
  23. });
  1. services.AddSignalR()
  2. .AddMessagePackProtocol()
  3. .AddStackExchangeRedis(o =>
  4. {
  5. o.ConnectionFactory = async writer =>
  6. {
  7. var config = new ConfigurationOptions
  8. {
  9. AbortOnConnectFail = false
  10. };
  11. config.EndPoints.Add(IPAddress.Loopback, 0);
  12. config.SetDefaultPorts();
  13. var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
  14. connection.ConnectionFailed += (_, e) =>
  15. {
  16. Console.WriteLine("Connection to Redis failed.");
  17. };
  18. if (!connection.IsConnected)
  19. {
  20. Console.WriteLine("Did not connect to Redis.");
  21. }
  22. return connection;
  23. };
  24. });

Redis 群集Redis Clustering

Redis 聚类分析是一种通过使用多个 Redis 服务器实现高可用性的方法。群集不是正式支持的,但它可能会起作用。

后续步骤Next steps

有关详细信息,请参阅以下资源: