当一个Web应用程序达到一台服务器能力限制,即请求处理数量限制之后,有2种解决方案:纵向扩展和横向扩展。

  • 纵向扩展即用更强的服务器(或虚拟机),或为当前的服务器添加更多的内存,CPU等
  • 横向扩展即添加多台服务器或者虚拟机来做负载均衡

纵向扩展的问题是,服务器的配置升级的费用比较高,而且总有升级的极限,很容易就再次达到限制。而横向扩展就没有这个限制,不同的用户可以被分流到不同的服务器,从而解决负载问题

但是这样的横向解决方案,会有一个问题,即用户被分流到不同SignalR服务器之后, 不同服务器上的用户就没有办法同步消息。

以一个聊天室程序为例,可能用户A,用户B被分流到服务器A, 用户C被分流到服务器B, 当用户A发送普通广播消息, 用户B因为和用户A分流到同一台服务器,所以能收到这条消息,用户C因为不在服务器A上,所以就没有办法收到这条消息。

底板(backplane)

Signal引入了一个底板的概念来解决不同服务器之间同步的问题。如果SignalR启用底板功能,每个应用实例发送消息的消息都会先传输到底板,底板会向所有连接的服务器发送同步消息,每个SignalR实例会把接收到的消息保存在内存中,然后同步给连接该实例的客户端。这样就解决了消息不同步的问题。

但是正因为有了底板机制,与单服务器SignalR应用相比,端到端通信和高并发应用的速度会减慢,同时发送的消息数量会减少,因为所有的客户端消息都是高频率的发送到SignalR服务器,SignalR服务器发送该消息到底板,底板再和所有的服务器同步消息,最在才通知到所有的连接客户端,所以对于这2种应用场景最适合还是单服务器SignalR应用。

底板最适合的是服务器广播,股市报价或者比赛文字直播就是最好的例子,因为所有的客户端都是被动接受消息,服务器端可以控制同时发送消息的数量。

SignalR默认支持的三种底板

  • Azure Service Bus
  • Redis
  • SQL Server

SignalR使用SQL Server做横向扩展

底板功能需要SQL Server 2005或以上版本的支持(精简版除外)。

配置数据库

  1. 打开SQL Server管理器,创建新的数据库SignalR
  2. 使用一下命令检查数据库是否支持Service Broker
SELECT [name], [service_broker_guid], [is_broker_enabled]

FROM [master].[sys].[databases]
  1. 如果SignalR的is_broker_enabled标志是false, 请输入以下命令启用Service Broker
ALTER DATABASE YOUR_DATABASE SET ENABLE_BROKER

Service Broker

Service Broker为SQL Server提供的原生的消息队列功能,启用Service Broker可以使底板更有效率的更新同步消息。但是不启用Service Broker, 底板依然可以运作。

创建项目

参照学习笔记(三)的代码,创建以下解决方案

ScaleoutSqlServer, ScaleoutSqlServer2与之前学习笔记(三)SignalRSelfHost代码完全相同

ChatRoom和ChatRoom2与与之前学习笔记(三)ChatRoom的代码完全相同

引入SQL Server底板支持

打开Package Manage Console面板,输入以下命令, 分别对

Install-Package Microsoft.AspNet.SignalR.SqlServer

启用SQL Server底板

打开ScaleoutSqlServer和ScaleoutSqlServer2工程中的Program.cs

ScaleoutSqlServer

class Program

    {

        static void Main(string[] args)

        {

            using (WebApp.Start<Startup>("http://localhost:9021"))

            {

                Console.WriteLine("Server started.");

                Console.Read();

            }

        }

    }

 

    class Startup

    {

        public void Configuration(IAppBuilder app)

        {

            // Any connection or hub wire up and configuration should go here

            string sqlConnectionString = "Server=.;Initial Catalog=SignalR; Integrated Security=true";

            GlobalHost.DependencyResolver.UseSqlServer(sqlConnectionString);

            app.UseCors(CorsOptions.AllowAll);

            app.MapSignalR();

        }

}

ScaleoutSqlServer2

class Program

    {

        static void Main(string[] args)

        {

            using (WebApp.Start<Startup>("http://localhost:9032"))

            {

                Console.WriteLine("Server started.");

                Console.Read();

            }

        }

    }

 

    class Startup

    {

        public void Configuration(IAppBuilder app)

        {

            // Any connection or hub wire up and configuration should go here

            string sqlConnectionString = "Server=.;Initial Catalog=SignalR; Integrated Security=true";

            GlobalHost.DependencyResolver.UseSqlServer(sqlConnectionString);

            app.UseCors(CorsOptions.AllowAll);

            app.MapSignalR();

        }

}

前台页面链接不同的SignalR服务器

修改ChatRoom, ChatRoom2中的ChatRoom.html

ChatRoom

<script src="Scripts/jquery.signalR-2.2.2.min.js"></script>

    <!--<script src="signalr/hubs"></script>-->

    <script src="http://localhost:9021/signalr/hubs"></script>

 

    <script type="text/javascript">

        $(function () {

 

            $.connection.hub.url = 'http://localhost:9021/signalr';

ChatRoom2

<script src="Scripts/jquery.signalR-2.2.2.min.js"></script>

    <!--<script src="signalr/hubs"></script>-->

    <script src="http://localhost:9032/signalr/hubs"></script>

 

    <script type="text/javascript">

        $(function () {

 

            $.connection.hub.url = 'http://localhost:9032/signalr';

最终效果

分别启动2个SignalR服务器, 并分别打开2个ChatRoom.html页面。

虽然2个Web应用程序访问的是不同的SignalR服务器,但是他们之间的消息同步了。

SignalR学习笔记(五) 横向扩展之SQL Server的更多相关文章

  1. Sharepoint2013商务智能学习笔记之Excel Service展示Sql Server数据Demo(五)

    第一步,打开Excel新建空白工作簿 第二步,使用Excel连接sql 数据库 第三步,画图 第四步 添加筛选器 最后效果如下: 第五步,将Excel上传到sharepoint任意文档库,并直接点击 ...

  2. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  3. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  4. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  6. SignalR学习笔记(二)高并发应用

    虽然SignalR借助Websocket提供了很强大的实时通讯能力,但是在有些实时通讯非常频繁的场景之下,如果使用不当,还是会导致服务器,甚至客户端浏览器崩溃. 以下是一个实时拖拽方块项目的优化过程 ...

  7. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  8. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  9. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

随机推荐

  1. SpringBoot简单入门

    一.创建SpringBoot项目 1.创建maven项目,pom引入springboot父级启动器(starter)依赖: <?xml version="1.0" encod ...

  2. 源生API解析XML文档与dom4j解析XML文档

    一.XML语言 XML是一种可扩展的标记语言,是一种强类型的语言,类似HTML(超文本标记语言,是一种弱类型的语言).XML是一种通用的数据交换格式(关系型数据库),综上所诉:XML可以传输数据,也可 ...

  3. Objective-C代码简写

      NSNumber 所有的[NSNumber numberWith…:]方法都可以简写了: [NSNumber numberWithChar:‘X’] 简写为 @‘X’; [NSNumber num ...

  4. Spring保护方法

    Spring保护方法 一.使用注解保护方法 1.@Secured 由Spring Security提供,首先需要启用基于注解的方法安全性: @EnableGlobalMethodSecurity(se ...

  5. nodejs, 阿里oss上传下载图片

    const archiver = require('archiver')const send = require('koa-send')const oss = require('ali-oss').W ...

  6. [POJ1961]Period (KMP)

    题意 求字符串s的最小循环元长度和循环次数 思路 s[1~i]满足循环元要len能整除i并且s[len+1~i]=s[1~i-len] 代码 #include<cstdio> #inclu ...

  7. VS Code 常用插件

    1.Chinese (Simplified) Language Pack for Visual Studio Code              VS Code软件汉化 2.Auto Close Ta ...

  8. Go语言基础之接口

    Go语言基础之接口 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节. 接口 接口介绍 在Go语言中接口(interface)是一种类型,一种抽象的类 ...

  9. 用Group by分组后,取每组的前3条记录,怎么取?

    使用子查询进行查询 SELECT * FROM home_content a WHERE ( SELECT count(id) FROM home_content WHERE class_link = ...

  10. [Educational Round 13][Codeforces 678F. Lena and Queries]

    题目连接:678F - Lena and Queries 题目大意:要求对一个点集实现二维点对的插入,删除,以及询问\(q\):求\(max(x\cdot q+y)\) 题解:对每个点集内的点\(P( ...