SignalR学习笔记(五) 横向扩展之SQL Server
当一个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或以上版本的支持(精简版除外)。
配置数据库
- 打开SQL Server管理器,创建新的数据库SignalR
- 使用一下命令检查数据库是否支持Service Broker
SELECT [name], [service_broker_guid], [is_broker_enabled] FROM [master].[sys].[databases]
- 如果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的更多相关文章
- Sharepoint2013商务智能学习笔记之Excel Service展示Sql Server数据Demo(五)
第一步,打开Excel新建空白工作簿 第二步,使用Excel连接sql 数据库 第三步,画图 第四步 添加筛选器 最后效果如下: 第五步,将Excel上传到sharepoint任意文档库,并直接点击 ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- SignalR学习笔记(二)高并发应用
虽然SignalR借助Websocket提供了很强大的实时通讯能力,但是在有些实时通讯非常频繁的场景之下,如果使用不当,还是会导致服务器,甚至客户端浏览器崩溃. 以下是一个实时拖拽方块项目的优化过程 ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
随机推荐
- list学习内容总结
list定义:list[]或者[]内任意类型的内容,多个用逗号分开 name1 = list(['Cyberpunk2077', 'Jim', 2077]) name2 = list('Cyberpu ...
- 创建线程的第三种方式——使用Callable接口
Callable是类似于Runnable的接口,实现Callable的类和实现Runnable的类都是可被其他线程执行的任务. 优点:有返回值 缺点:实现繁琐 简单实现: CallableAndFut ...
- NOIP2012提高组day2 T2借教室
这题骗分可以骗到满分(可能是数据不太强给强行过去了) 这道题如果是按照题意去模拟用循环去修改区间的话只有45分,正解是二分+差分数组,骗分也是差分数组但是没有使用二分,时间复杂度在最坏的情况下是O(n ...
- css3 图片阴影
box-shadow:1px 2px 4px #999999; 效果:
- js活jQuery实现动态添加、移除css/js文件
下面是在项目中用到的,直接封装好的函数,拿去在js中直接调用就可以实现css.js文件的动态引入与删除.代码如下 动态加载,移除,替换css/js文件 // 动态添加css文件 function ad ...
- console.log
其实,console.log 不仅仅有一下应用 console.log() 这个应该是最常用的 console.error() 输出错误信息 会以红色显示 console.assert(bool,”i ...
- python学习:字典
字典 1.查询内存地址 a = 10 print(id(a)) b = a print(id(b)) b = 15 print(id(b)) 2. 数据类型 不可变类型:整型.字符串.元组 可变类型: ...
- 181102 Windows下安装kivy(用python写APP)
了解到Instgram,知乎等APP是用python写的.我也决定学习用python写APP.这里我们需要安装kivy. 环境:win7,python3.6 安装方式:DOS命令窗口 注意事项:目前不 ...
- STS(Spring Tool Suite)下SSM(Spring+SpringMVC+Mybatis)框架搭建(二)
继完成controller配置并使用controller实现页面跳转,现连接数据库进行登录. 在SSM框架中,使用Mybatis与数据库连接,因此需要配置关于mybatis的配置. 废话少说直接开始: ...
- 初入linux系统
作为微软的老铁粉了,看到微软进军linux这么久了,是时候该跟上脚本了,不然该落后了,脚步是如此之快,着实让我吃了一惊,说干就干, 绝不是开玩笑的,谁也阻止不了.net开源,跨平台的脚步了.以前别人说 ...