设置 Redis 底板以实现 ASP.NET Core SignalR 横向扩展

作者:Andrew Stanton-NurseBrady GasterTom Dykstra

本文介绍在特定于 SignalR 的方面设置要用于横向扩展 ASP.NET Core SignalR 应用的 Redis 服务器。

警告

本文介绍连接字符串的使用。 使用本地数据库时,用户无需进行身份验证,但在生产环境中,连接字符串有时包括进行身份验证的密码。 资源所有者密码凭据(ROPC)是在生产数据库中应避免的安全风险。 生产应用应使用可用的最安全的身份验证流。 有关部署到测试或生产环境的应用的身份验证的详细信息,请参阅 安全身份验证流

设置 Redis 底板

  • 部署 Redis 服务器。

    重要

    对于生产用途,建议仅当 Redis 底板在与 SignalR 应用所在的同一数据中心中运行时使用它。 否则,网络延迟会导致性能降低。 如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。

    有关更多信息,请参见以下资源:

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

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis
  • 通过在 Program.cs 文件中调用 builder.Build()) 的行之前添加以下行来调用 AddStackExchangeRedis

    builder.Services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
    
  • 根据需要配置选项:

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

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

    builder.Services.AddSignalR()
      .AddStackExchangeRedis(connectionString, options => {
          options.Configuration.ChannelPrefix = RedisChannel.Literal("MyApp");
      });
    

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

    有关 Redis 选项的信息,请参阅 StackExchange Redis 文档

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

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

  • 为粘性会话配置你的服务器场负载均衡软件。 下面一些示例文档介绍了如何实现此目标:

Redis 服务器错误

当 Redis 服务器关闭时,SignalR 将引发异常,指示不会传递消息。 一些典型的异常消息:

  • 写入消息失败
  • 无法调用中心方法“MethodName”
  • 连接到 Redis 失败

SignalR 不会缓冲消息以在服务器恢复时发送它们。 Redis 服务器关闭时任何发送的消息将丢失。

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

自定义连接失败的行为

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

services.AddSignalR()
        .AddMessagePackProtocol()
        .AddStackExchangeRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Redis 群集

Redis 群集利用多个同时处于活动状态的 Redis 服务器来实现高可用性。 将 Redis 群集用作 SignalR 的底板时,消息将传递到群集的所有节点,而无需对应用进行代码修改。

需要在群集中的节点数与底板的吞吐量之间进行权衡。 节点数越多,群集的可用性越高,但吞吐量会变低,因为必须将消息传输到群集中的所有节点。

在 SignalR 应用中,使用下列任一方法将所有可能的 Redis 节点包含在内:

  • 列出连接字符串中的节点(用逗号分隔)。
  • 如果使用自定义行为来处理连接失败情况,请将节点添加到 ConfigurationOptions.Endpoints

后续步骤

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

本文介绍在特定于 SignalR 的方面设置要用于横向扩展 ASP.NET Core SignalR 应用的 Redis 服务器。

警告

本文介绍连接字符串的使用。 使用本地数据库时,用户无需进行身份验证,但在生产环境中,连接字符串有时包括进行身份验证的密码。 资源所有者密码凭据(ROPC)是在生产数据库中应避免的安全风险。 生产应用应使用可用的最安全的身份验证流。 有关部署到测试或生产环境的应用的身份验证的详细信息,请参阅 安全身份验证流

设置 Redis 底板

  • 部署 Redis 服务器。

    重要

    对于生产用途,建议仅当 Redis 底板在与 SignalR 应用所在的同一数据中心中运行时使用它。 否则,网络延迟会导致性能降低。 如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。

    有关更多信息,请参见以下资源:

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

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis
  • 通过在 Program.cs 文件中调用 builder.Build()) 的行之前添加以下行来调用 AddStackExchangeRedis

    builder.Services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
    
  • 根据需要配置选项:

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

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

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

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

    有关 Redis 选项的信息,请参阅 StackExchange Redis 文档

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

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

  • 为粘性会话配置你的服务器场负载均衡软件。 下面一些示例文档介绍了如何实现此目标:

Redis 服务器错误

当 Redis 服务器关闭时,SignalR 将引发异常,指示不会传递消息。 一些典型的异常消息:

  • 写入消息失败
  • 无法调用中心方法“MethodName”
  • 连接到 Redis 失败

SignalR 不会缓冲消息以在服务器恢复时发送它们。 Redis 服务器关闭时任何发送的消息将丢失。

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

自定义连接失败的行为

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

services.AddSignalR()
        .AddMessagePackProtocol()
        .AddStackExchangeRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Redis 群集

Redis 群集利用多个同时处于活动状态的 Redis 服务器来实现高可用性。 将 Redis 群集用作 SignalR 的底板时,消息将传递到群集的所有节点,而无需对应用进行代码修改。

需要在群集中的节点数与底板的吞吐量之间进行权衡。 节点数越多,群集的可用性越高,但吞吐量会变低,因为必须将消息传输到群集中的所有节点。

在 SignalR 应用中,使用下列任一方法将所有可能的 Redis 节点包含在内:

  • 列出连接字符串中的节点(用逗号分隔)。
  • 如果使用自定义行为来处理连接失败情况,请将节点添加到 ConfigurationOptions.Endpoints

后续步骤

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

本文介绍在特定于 SignalR 的方面设置要用于横向扩展 ASP.NET Core SignalR 应用的 Redis 服务器。

警告

本文介绍连接字符串的使用。 使用本地数据库时,用户无需进行身份验证,但在生产环境中,连接字符串有时包括进行身份验证的密码。 资源所有者密码凭据(ROPC)是在生产数据库中应避免的安全风险。 生产应用应使用可用的最安全的身份验证流。 有关部署到测试或生产环境的应用的身份验证的详细信息,请参阅 安全身份验证流

设置 Redis 底板

  • 部署 Redis 服务器。

    重要

    对于生产用途,建议仅当 Redis 底板在与 SignalR 应用所在的同一数据中心中运行时使用它。 否则,网络延迟会导致性能降低。 如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。

    有关更多信息,请参见以下资源:

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

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis
  • 通过在 Program.cs 文件中调用 builder.Build()) 的行之前添加以下行来调用 AddStackExchangeRedis

    builder.Services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
    
  • 根据需要配置选项:

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

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

    builder.Services.AddSignalR()
      .AddStackExchangeRedis(connectionString, options => {
          options.Configuration.ChannelPrefix = RedisChannel.Literal("MyApp");
      });
    

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

    有关 Redis 选项的信息,请参阅 StackExchange Redis 文档

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

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

  • 为粘性会话配置你的服务器场负载均衡软件。 下面一些示例文档介绍了如何实现此目标:

Redis 服务器错误

当 Redis 服务器关闭时,SignalR 将引发异常,指示不会传递消息。 一些典型的异常消息:

  • 写入消息失败
  • 无法调用中心方法“MethodName”
  • 连接到 Redis 失败

SignalR 不会缓冲消息以在服务器恢复时发送它们。 Redis 服务器关闭时任何发送的消息将丢失。

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

自定义连接失败的行为

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

services.AddSignalR()
        .AddMessagePackProtocol()
        .AddStackExchangeRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Redis 群集

Redis 群集利用多个同时处于活动状态的 Redis 服务器来实现高可用性。 将 Redis 群集用作 SignalR 的底板时,消息将传递到群集的所有节点,而无需对应用进行代码修改。

需要在群集中的节点数与底板的吞吐量之间进行权衡。 节点数越多,群集的可用性越高,但吞吐量会变低,因为必须将消息传输到群集中的所有节点。

在 SignalR 应用中,使用下列任一方法将所有可能的 Redis 节点包含在内:

  • 列出连接字符串中的节点(用逗号分隔)。
  • 如果使用自定义行为来处理连接失败情况,请将节点添加到 ConfigurationOptions.Endpoints

后续步骤

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

本文介绍在特定于 SignalR 的方面设置要用于横向扩展 ASP.NET Core SignalR 应用的 Redis 服务器。

警告

本文介绍连接字符串的使用。 使用本地数据库时,用户无需进行身份验证,但在生产环境中,连接字符串有时包括进行身份验证的密码。 资源所有者密码凭据(ROPC)是在生产数据库中应避免的安全风险。 生产应用应使用可用的最安全的身份验证流。 有关部署到测试或生产环境的应用的身份验证的详细信息,请参阅 安全身份验证流

设置 Redis 底板

  • 部署 Redis 服务器。

    重要

    对于生产用途,建议仅当 Redis 底板在与 SignalR 应用所在的同一数据中心中运行时使用它。 否则,网络延迟会导致性能降低。 如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。

    有关更多信息,请参见以下资源:

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

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis
  • Startup.ConfigureServices 方法中,调用 AddStackExchangeRedis

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

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

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

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

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

    有关 Redis 选项的信息,请参阅 StackExchange Redis 文档

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

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

  • 为粘性会话配置你的服务器场负载均衡软件。 下面一些示例文档介绍了如何实现此目标:

Redis 服务器错误

当 Redis 服务器关闭时,SignalR 将引发异常,指示不会传递消息。 一些典型的异常消息:

  • 写入消息失败
  • 无法调用中心方法“MethodName”
  • 连接到 Redis 失败

SignalR 不会缓冲消息以在服务器恢复时发送它们。 Redis 服务器关闭时任何发送的消息将丢失。

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

自定义连接失败的行为

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

services.AddSignalR()
        .AddMessagePackProtocol()
        .AddStackExchangeRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Redis 群集

Redis 群集利用多个同时处于活动状态的 Redis 服务器来实现高可用性。 将 Redis 群集用作 SignalR 的底板时,消息将传递到群集的所有节点,而无需对应用进行代码修改。

需要在群集中的节点数与底板的吞吐量之间进行权衡。 节点数越多,群集的可用性越高,但吞吐量会变低,因为必须将消息传输到群集中的所有节点。

在 SignalR 应用中,使用下列任一方法将所有可能的 Redis 节点包含在内:

  • 列出连接字符串中的节点(用逗号分隔)。
  • 如果使用自定义行为来处理连接失败情况,请将节点添加到 ConfigurationOptions.Endpoints

后续步骤

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

本文介绍在特定于 SignalR 的方面设置要用于横向扩展 ASP.NET Core SignalR 应用的 Redis 服务器。

警告

本文介绍连接字符串的使用。 使用本地数据库时,用户无需进行身份验证,但在生产环境中,连接字符串有时包括进行身份验证的密码。 资源所有者密码凭据(ROPC)是在生产数据库中应避免的安全风险。 生产应用应使用可用的最安全的身份验证流。 有关部署到测试或生产环境的应用的身份验证的详细信息,请参阅 安全身份验证流

设置 Redis 底板

  • 部署 Redis 服务器。

    重要

    对于生产用途,建议仅当 Redis 底板在与 SignalR 应用所在的同一数据中心中运行时使用它。 否则,网络延迟会导致性能降低。 如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。

    有关更多信息,请参见以下资源:

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

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis
  • Startup.ConfigureServices 方法中,调用 AddStackExchangeRedis

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

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

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

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

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

    有关 Redis 选项的信息,请参阅 StackExchange Redis 文档

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

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

  • 为粘性会话配置你的服务器场负载均衡软件。 下面一些示例文档介绍了如何实现此目标:

Redis 服务器错误

当 Redis 服务器关闭时,SignalR 将引发异常,指示不会传递消息。 一些典型的异常消息:

  • 写入消息失败
  • 无法调用中心方法“MethodName”
  • 连接到 Redis 失败

SignalR 不会缓冲消息以在服务器恢复时发送它们。 Redis 服务器关闭时任何发送的消息将丢失。

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

自定义连接失败的行为

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

services.AddSignalR()
        .AddMessagePackProtocol()
        .AddStackExchangeRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Redis 群集

Redis 群集利用多个同时处于活动状态的 Redis 服务器来实现高可用性。 将 Redis 群集用作 SignalR 的底板时,消息将传递到群集的所有节点,而无需对应用进行代码修改。

需要在群集中的节点数与底板的吞吐量之间进行权衡。 节点数越多,群集的可用性越高,但吞吐量会变低,因为必须将消息传输到群集中的所有节点。

在 SignalR 应用中,使用下列任一方法将所有可能的 Redis 节点包含在内:

  • 列出连接字符串中的节点(用逗号分隔)。
  • 如果使用自定义行为来处理连接失败情况,请将节点添加到 ConfigurationOptions.Endpoints

后续步骤

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

本文介绍在特定于 SignalR 的方面设置要用于横向扩展 ASP.NET Core SignalR 应用的 Redis 服务器。

警告

本文介绍连接字符串的使用。 使用本地数据库时,用户无需进行身份验证,但在生产环境中,连接字符串有时包括进行身份验证的密码。 资源所有者密码凭据(ROPC)是在生产数据库中应避免的安全风险。 生产应用应使用可用的最安全的身份验证流。 有关部署到测试或生产环境的应用的身份验证的详细信息,请参阅 安全身份验证流

设置 Redis 底板

  • 部署 Redis 服务器。

    重要

    对于生产用途,建议仅当 Redis 底板在与 SignalR 应用所在的同一数据中心中运行时使用它。 否则,网络延迟会导致性能降低。 如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。

    有关更多信息,请参见以下资源:

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

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis - 依赖于 StackExchange.Redis 2.X.X。这是建议用于 ASP.NET Core 2.2 及更高版本的包。
    • Microsoft.AspNetCore.SignalR.Redis - 依赖于 StackExchange.Redis 1.X.X。此包未包含在 ASP.NET Core 3.0 及更高版本中。
  • Startup.ConfigureServices 方法中,调用 AddStackExchangeRedis

    services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
    

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

  • 根据需要配置选项:

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

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

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

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

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

有关 Redis 选项的信息,请参阅 StackExchange Redis 文档

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

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

  • 为粘性会话配置你的服务器场负载均衡软件。 下面一些示例文档介绍了如何实现此目标:

Redis 服务器错误

当 Redis 服务器关闭时,SignalR 将引发异常,指示不会传递消息。 一些典型的异常消息:

  • 写入消息失败
  • 无法调用中心方法“MethodName”
  • 连接到 Redis 失败

SignalR 不会缓冲消息以在服务器恢复时发送它们。 Redis 服务器关闭时任何发送的消息将丢失。

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

自定义连接失败的行为

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

services.AddSignalR()
        .AddMessagePackProtocol()
        .AddStackExchangeRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Redis 群集

Redis 群集利用多个同时处于活动状态的 Redis 服务器来实现高可用性。 将 Redis 群集用作 SignalR 的底板时,消息将传递到群集的所有节点,而无需对应用进行代码修改。

需要在群集中的节点数与底板的吞吐量之间进行权衡。 节点数越多,群集的可用性越高,但吞吐量会变低,因为必须将消息传输到群集中的所有节点。

在 SignalR 应用中,使用下列任一方法将所有可能的 Redis 节点包含在内:

  • 列出连接字符串中的节点(用逗号分隔)。
  • 如果使用自定义行为来处理连接失败情况,请将节点添加到 ConfigurationOptions.Endpoints

后续步骤

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

本文介绍在特定于 SignalR 的方面设置要用于横向扩展 ASP.NET Core SignalR 应用的 Redis 服务器。

警告

本文介绍连接字符串的使用。 使用本地数据库时,用户无需进行身份验证,但在生产环境中,连接字符串有时包括进行身份验证的密码。 资源所有者密码凭据(ROPC)是在生产数据库中应避免的安全风险。 生产应用应使用可用的最安全的身份验证流。 有关部署到测试或生产环境的应用的身份验证的详细信息,请参阅 安全身份验证流

设置 Redis 底板

  • 部署 Redis 服务器。

    重要

    对于生产用途,建议仅当 Redis 底板在与 SignalR 应用所在的同一数据中心中运行时使用它。 否则,网络延迟会导致性能降低。 如果 SignalR 应用在 Azure 云中运行,我们建议使用 Azure SignalR 服务,而不是 Redis 底板。

    有关更多信息,请参见以下资源:

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

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

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

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

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

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

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

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

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

  • 为粘性会话配置你的服务器场负载均衡软件。 下面一些示例文档介绍了如何实现此目标:

Redis 服务器错误

当 Redis 服务器关闭时,SignalR 将引发异常,指示不会传递消息。 一些典型的异常消息:

  • 写入消息失败
  • 无法调用中心方法“MethodName”
  • 连接到 Redis 失败

SignalR 不会缓冲消息以在服务器恢复时发送它们。 Redis 服务器关闭时任何发送的消息将丢失。

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

自定义连接失败的行为

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

services.AddSignalR()
        .AddRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Redis 群集

Redis 群集利用多个同时处于活动状态的 Redis 服务器来实现高可用性。 将 Redis 群集用作 SignalR 的底板时,消息将传递到群集的所有节点,而无需对应用进行代码修改。

需要在群集中的节点数与底板的吞吐量之间进行权衡。 节点数越多,群集的可用性越高,但吞吐量会变低,因为必须将消息传输到群集中的所有节点。

在 SignalR 应用中,使用下列任一方法将所有可能的 Redis 节点包含在内:

  • 列出连接字符串中的节点(用逗号分隔)。
  • 如果使用自定义行为来处理连接失败情况,请将节点添加到 ConfigurationOptions.Endpoints

后续步骤

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