SignalR 横向扩展与 Redis 背板

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

在“ 开始使用 signalr ”一文中,我通过一些简单实用的示例对 signalr 进行了温和的介绍。压倒性的反应表明,并不是我一个人认为这是一项通过网络实现实时推送通知的出色技术。

Web 应用程序经常面临必须扩展以处理大量客户端的挑战,signalr 应用程序也不例外。在这个例子中,我们将看到一种使用称为背板的东西来扩展信号器应用程序的方法。

信号器中的横向扩展

signalr 中的 scaleout 简介 ”(官方文档)描述了 signalr 应用程序如何使用多个服务器来处理越来越多的客户端。当服务器需要推送更新时,它首先通过称为 背板的 消息总线推送更新。这会将它传送到其他服务器,然后这些服务器可以将更新转发给它们各自的客户端。

根据官方文档,使用 azure、redis 或 sql server 作为背板支持 scaleout。存在第三方包以支持其他渠道,例如 signalr.rabbitmq

使用 redis 的横向扩展示例

signalr中的scaleout介绍 》(官方文档)描述了如何使用signalr作为背板。为了演示这一点,我将基于我的“ signalr 入门 ”一文中的 聊天示例代码 进行构建。

我们使用 redis 进行横向扩展所需要做的就是安装 microsoft.aspnet.signalr.redis nuget 包,然后在启动类中进行如下设置:


 public void configuration(iappbuilder app)
        {
            globalhost.dependencyresolver.useredis("192.168.1.66", 6379, null, "signalrchat");
            app.mapsignalr();
        }

在上面的代码中,我指定了 redis 服务器的主机和端口、密码(在本例中为 null,因为我没有),以及信号器将用于分发消息的发布/订阅频道的名称。

要对此进行测试,您可以从 redis 下载 页面获取一个 redis 服务器。存在适用 于 Windows 的 redis 版本 ,非常适合测试内容,但请记住,生产环境不正式支持它们。

现在实际测试它,我在两台不同的机器上设置了相同的扩展增强聊天应用程序,并订阅了 redis 发布/订阅频道:

观看发布/订阅频道可以揭示 signalr 在幕后所做的事情。当应用程序在每台机器上初始化时,会有特定的消息经过,您还可以看到经过的实际数据消息。所以当你在聊天中写消息时,你也可以在发布/订阅频道中看到它。

但更好的是,您还会在连接到另一台机器的客户端(浏览器)上看到它:

您需要了解这里的神奇之处在于,它们不是连接到同一服务器的两个浏览器;他们实际上是在与不同机器上的不同服务器通信。尽管如此,由于背板,消息设法到达所有客户端,在本例中是 redis。

注意事项

所以我已经展示了将 signalr 扩展到多个服务器是多么容易:您需要安装一个 nuget 包并添加一行代码。我实际上已经在两台机器上测试过它。

但这并不是真正的横向扩展。我没有进行大规模测试的资源,只是想通过本文展示如何实现 scaleout。横向扩展的实际好处取决于应用程序。正如 官方文档 所警告的那样,添加背板会产生开销,并且在某些情况下可能成为瓶颈。在开始之前,您确实需要研究您的应用程序是否适合这种横向扩展。