.NET下数据库的负载均衡“经典方案”(大项目必备,建议收藏)
【前言】
本文讲述的“数据库负载均衡”方案,为市面上最经典(没有之一),由.NET界骨灰级大佬推出。采用该技术方案的大公司,一年省下了几个亿的支出。
【正文】
支持.Net Core(2.0及以上) 与 .Net Framework(4.5及以上)
可以部署在Docker, Windows, Linux, Mac。
为了演示数据库的负载均衡(Load Balance),我们先创建三个数据库,它们的名字分别为YZZ、YZZ1、YZZ2。然后在这三个数据库中分别创建表t_Student,这些表的结构一样,内容稍有差异,见下图:
|
YZZ中t_Student的内容 --------------------- Id Name Age 1 张安 25 2 王鑫 22 3 周云 20 |
YZZ1中t_Student的内容 --------------------- Id Name Age 1 张安1 25 2 王鑫1 22 3 周云1 20 |
YZZ2中t_Student的内容 --------------------- Id Name Age 1 张安2 25 2 王鑫2 22 3 周云2 20 |
接下来,
若是在.Net Core环境下,我们需要创建一个名为DeveloperSharp.json的配置文件,并在其中设置如上三个数据源的负载均衡策略。文件内容如下:
{
"DeveloperSharp":
{
"DatabaseClusterList":
[
{
"Id":"StudentData",
"DatabaseCluster":
[
{
"Id":"A1",
"Enable":"true",
"Weight":"100",
"DatabaseType":"SqlServer",
"ConnectionString":"Server=localhost;Database=YZZ;Uid=sa;Pwd=123"
},
{
"Id":"A2",
"Enable":"true",
"Weight":"100",
"DatabaseType":"SqlServer",
"ConnectionString":"Server=localhost;Database=YZZ1;Uid=sa;Pwd=123"
},
{
"Id":"A3",
"Enable":"true",
"Weight":"100",
"DatabaseType":"SqlServer",
"ConnectionString":"Server=localhost;Database=YZZ2;Uid=sa;Pwd=123"
}
]
}
]
}
}
若是在.Net Framework环境下,我们需要创建一个名为DeveloperSharp.xml的配置文件,并在其中设置如上三个数据源的负载均衡策略。文件内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<DeveloperSharp>
<DatabaseClusterList>
<DatabaseCluster Id="StudentData">
<Database Id="A1" Enable="true" Weight="100" DatabaseType="SqlServer" ConnectionString="Server=localhost;Database=YZZ;Uid=sa;Pwd=123"/>
<Database Id="A2" Enable="true" Weight="100" DatabaseType="SqlServer" ConnectionString="Server=localhost;Database=YZZ1;Uid=sa;Pwd=123"/>
<Database Id="A3" Enable="true" Weight="100" DatabaseType="SqlServer" ConnectionString="Server=localhost;Database=YZZ2;Uid=sa;Pwd=123"/>
</DatabaseCluster>
</DatabaseClusterList>
</DeveloperSharp>

对此json/xml配置文件说明如下:
(1) 每一个DatabaseCluster节点代表了一组数据库,此节点的Id值(本文示例值是:StudentData)后续会在程序中使用。
(2) Database节点中的Weight属性代表了使用权重。本文示例的三个数据库的Weight值分别是100、100、100,则这三个数据库的负载均衡使用分配比例将会是1:1:1。若把这三个值分别设置为100、50、50,则这三个数据库的使用分配比例将会变为2:1:1。设置成你想要的比例吧。
(3) Database节点中的Enable属性代表了是否可用。true代表可用,false代表不可用。
(4) 可通过把DatabaseType属性的值设置为“MySql”、“SQLite”、“PostgreSql”、“Oracle”、其它等等,从而支持各种类数据库。(本文讲述的是“同种数据库”的负载均衡。若是需要“异种数据库”的负载均衡,请参看 数据库的负载均衡(续) 这篇文章)
接下来,我们看看怎么在程序中使用上述的这组数据库及其配置文件,来实现负载均衡。
为了演示负载均衡效果,我们首先在Visual Studio中新建一个控制台工程,并为工程引用添加了Entity Framework组件作为访问数据库的工具(你也可以换成其它数据库访问工具,原理一样,完全不受影响)。
然后,我们做如下四个操作。
【第一步】:从NuGet引用DeveloperSharp包(需要是最新版本)。
【第二步】:链接负载均衡配置文件:
若是在.Net Core环境下,我们只需要把DeveloperSharp.json文件放到程序执行目录中(即bin目录下与dll、exe等文件的同一目录中)(放错了位置会报错)。
若是在.Net Framework环境下,我们需要在工程配置文件App.config中添加appSettings节点,节点内容如下:
<appSettings>
<add key="DatabaseType" value="" />
<add key="ConnectionString" value="" />
<add key="ErrorPage" value="" />
<add key="ErrorLog" value="D:\Test\Assist\log.txt" />
<add key="ConfigFile" value="D:\Test\Assist\DeveloperSharp.xml" />
</appSettings>
其中,ConfigFile的设置是为了链接前述的DeveloperSharp.xml这个配置文件。ErrorLog则是设置一个错误日志文件。它们均需要设置为文件的“绝对路径”(此处使用“绝对路径”而不是“相对路径”,一是有利于安全性,二是有利于分布式部署)
【第三步】:创建一个StudentLB.cs类文件,它就是数据库负载均衡的核心器件,内容如下:
//这个属性就是用作映射负载均衡。
//其“值”需设置为前述DeveloperSharp.json/xml配置文件中某个DatabaseCluster节点的Id值。
[DeveloperSharp.Structure.Model.LoadBalance.DataSourceCluster("StudentData")]
public class StudentLB : DeveloperSharp.Structure.Model.DataLayer
{
//类中没有任何代码
}
说明:“负载均衡器”类(本篇为:StudentLB类)必须继承自DeveloperSharp.Structure.Model.DataLayer类,并且在其上设置DeveloperSharp.Structure.Model.LoadBalance.DataSourceCluster属性的初始化值为DeveloperSharp.json/xml配置文件中某个DatabaseCluster节点的Id值。
【第四步】:为控制台应用类,添加通过负载均衡器(StudentLB类)访问数据库的代码,注意:核心代码就一行而已!!此示例连续3次访问数据库做同一操作,看会显示什么结果。如下:
class Program
{
static void Main(string[] args)
{
string NameList = ""; //第一次访问数据库
var SLB = (new StudentLB()) as DeveloperSharp.Structure.Model.DataLayer;
var db = new Entities(SLB.IDA.ConnectionString);//每次会根据配置的负载均衡策略输出对应的ConnectionString
t_Student Stu = db.t_Student.Where(t => t.Id == 3).FirstOrDefault();
NameList += Stu.Name; //第二次访问数据库
SLB = (new StudentLB()) as DeveloperSharp.Structure.Model.DataLayer;
db = new Entities(SLB.IDA.ConnectionString);//每次会根据配置的负载均衡策略输出对应的ConnectionString
Stu = db.t_Student.Where(t => t.Id == 3).FirstOrDefault();
NameList += Stu.Name; //第三次访问数据库
SLB = (new StudentLB()) as DeveloperSharp.Structure.Model.DataLayer;
db = new Entities(SLB.IDA.ConnectionString);//每次会根据配置的负载均衡策略输出对应的ConnectionString
Stu = db.t_Student.Where(t => t.Id == 3).FirstOrDefault();
NameList += Stu.Name; //输出
Console.WriteLine(NameList);
Console.ReadLine(); }
}
从以上示例代码我们可以清晰的得知:其实数据库链接字符串ConnectionString就是实现负载均衡的关键所在。而SLB.IDA.ConnectionString则每次会根据配置的负载均衡策略输出对应的链接字符串。
示例程序输出显示结果如下:
周云周云1周云2
运行有问题,需要技术支持?以及bug提交通道,请添加微信:894988403
运行有问题,需要技术支持?以及bug提交通道,请添加微信:894988403
最后提示两点:
(1)本文设置了一组数据库的负载均衡。但其实可以在DeveloperSharp.json/xml配置文件及程序中设置多组数据库的负载均衡。
(2)若要把一组数据库的负载均衡应用改为单数据库应用,只需要把DeveloperSharp.json/xml配置文件中DatabaseCluster节点下的Database节点数量设置为一个即可实现。所以,聪明的你以后可以把你所有的数据库访问代码改为此负载均衡模式,以便日后随时在单体/集群之间切换,以备不时之需:)
总结
本文技术点思路梳理:
- 创建用来实施负载均衡的一组数据库。
- 通过DeveloperSharp.json/xml来配置负载均衡策略。
- 调整DeveloperSharp.json的位置,或者,在App.config/Web.config中添加链接DeveloperSharp.xml的appSettings节点。
- 创建基于DeveloperSharp包的“负载均衡器”类(本篇为:StudentLB类)。
- 通过“负载均衡器”产生的ConnectionString链接数据库。
运行有问题,需要技术支持?以及bug提交通道,请添加微信:894988403
运行有问题,需要技术支持?以及bug提交通道,请添加微信:894988403
原文链接:http://www.developersharp.cc/content1.html
服务条款:http://www.developersharp.cc/buy.html
文章首发于公众号【.Net数字智慧化基地】,欢迎大家关注。

【.Net数字智慧化基地】:本号长期专注于.Net技术、软件架构、人工智能、工业互联网、智能制造、等领域。作者早年毕业于一流大学并已是IT科技领域成功人士。本号致力于提高圈内整体技术素养,为各类初、中、高级技术人员提供量身定制的个人成长服务,助力升职加薪。本号同时也为有数字化转型需求的各类企业提供深度咨询、指导服务。
.NET下数据库的负载均衡“经典方案”(大项目必备,建议收藏)的更多相关文章
- .NET下数据库的负载均衡(有趣实验)(续)
.NET下数据库的负载均衡(有趣实验)这篇文章发表后,受到了众多读者的关注与好评,其中不乏元老级程序员. 读者来信中询问最多的一个问题是:它是否能支持"异种数据库"的负载均衡?? ...
- .NET下数据库的负载均衡(有趣实验)
相关下载: 数据库的负载均衡-示例代码(dp1-DbBalance.rar) 数据库的负载均衡-示例代码(dp1-DbBalance.rar) 支持.Net/.Net Core/.Net Framew ...
- 微软Azure 经典模式下创建内部负载均衡(ILB)
微软Azure 经典模式下创建内部负载均衡(ILB) 使用之前一定要注意自己的Azure的模式,老版的为cloud service模式,新版为ARM模式(资源组模式) 本文适用于cloud servi ...
- 理解web服务器和数据库的负载均衡以及反向代理
这里的“负载均衡”是指在网站建设中应该考虑的“负载均衡”.假设我们要搭建一个网站:aaa.me,我们使用的web服务器每秒能处理100条请求,而aaa.me这个网站最火的时候也只是每秒99条请求,那么 ...
- 【Nginx】如何使用Nginx实现MySQL数据库的负载均衡?看完我懂了!!
写在前面 Nginx能够实现HTTP.HTTPS协议的负载均衡,也能够实现TCP协议的负载均衡.那么,问题来了,可不可以通过Nginx实现MySQL数据库的负载均衡呢?答案是:可以.接下来,就让我们一 ...
- Windows下apache+tomcat负载均衡
Windows下apache+tomcat负载均衡 网上已经有很多的资料,但是很多都比较零碎,需要整合一起才能搭建出理想的负载均衡,正好前段时间搭建了windows与linux下的负载均衡,在此记录, ...
- 介绍一下再Apache下的Tomcat负载均衡的一些使用问题
在负载均衡技术中,硬件设备是比较昂贵的,对于负载均衡的学习者如果不是在企业中应用或者是学员中学习,很少有机会能碰到实际操作的训练.(http://xz.8682222.com)所以,很多朋友都会选择软 ...
- NLB+ARR实现IIS下的高可用性负载均衡
NLB+ARR实现IIS下的高可用性负载均衡 场景: 高可用/可伸缩集群: NLB部署: 很简单, 暂略. 3.ARR部署 ARR全称叫Application Request Router, 是I ...
- Redis+PHP扩展的安装和Redis集群的配置 与 PHP负载均衡开发方案
以前有想过用 Memcache 实现M/S架构的负载均衡方案,直到听说了 Redis 后才发现它做得更好.发了几天时间研究了一下 Redis ,感觉真的很不错,特整理一下! 以下操作都是在 SUSE ...
- Linux环境下Nginx及负载均衡
Nginx 简介 Nginx 是一个高性能的 HTTP 和反向代理 Web 服务器,同时也提供了 IMAP/POP3/SMTP 服务.前向代理作为客户端的代理,服务端只知道代理的 IP 地址而不知道客 ...
随机推荐
- Selenium Grid入门详解
一.简介 Selenium是Selenium套件的一部分,它专门用于并行运行多个测试用例在不同的浏览器.操作系统和机器上 Selenium Grid主要使用 master-slaves或者hub-no ...
- SpringBoot定义优雅全局统一Restful API 响应框架四
如果没有看前面几篇文章请先看前面几篇 SpringBoot定义优雅全局统一Restful API 响应框架 SpringBoot定义优雅全局统一Restful API 响应框架二 SpringBoot ...
- STL------sort三种比较算子定义
sort的三种比较算子的定义方式 例:一道细碎的细节模拟题: http://newoj.acmclub.cn/contests/1258/problem/3 1932: 2018蓝桥杯培训-STL应用 ...
- 2022-12-19:大的国家。如果一个国家满足下述两个条件之一,则认为该国是 大国 : 面积至少为 300 万平方公里(即,3000000 km2),或者 人口至少为 2500 万(即 250000
2022-12-19:大的国家.如果一个国家满足下述两个条件之一,则认为该国是 大国 : 面积至少为 300 万平方公里(即,3000000 km2),或者 人口至少为 2500 万(即 250000 ...
- Django-5:前端模板路径设定TEMPLATES DIRS和调用
前端模板路径设定:'DIRS': [BASE_DIR / 'templates'] TEMPLATES = [ { 'BACKEND': 'django.template.backends.djang ...
- Github Copilot Chat 初体验
最近因为阳了的缘故一直躺在床上.今天终于从床上爬起来了.不是因为好透了,而是因为我收到了申请Copilot Chat preview 权限通过的邮件.实在忍不住,于是起床开电脑在咳嗽声中进行了一番体验 ...
- Nacos必知必会:这些知识点你一定要掌握!
前言 Nacos 是一个开源的服务发现.配置管理和服务治理平台,是阿里巴巴开源的一款产品. Nacos 可以帮助开发者更好地管理微服务架构中的服务注册.配置和发现等问题,提高系统的可靠性和可维护性. ...
- 烂怂if-else代码优化方案
0.问题概述 代码可读性是衡量代码质量的重要标准,可读性也是可维护性.可扩展性的保证,因为代码是连接程序员和机器的中间桥梁,要对双边友好.Quora 上有一个帖子: "What are so ...
- Simple CTF
来自tryhackme的Simple CTF IP:10.10.27.234 信息收集 端口扫描 nmap -sV -T4 10.10.27.234 可以看到三个端口 21/tcp 打开 ftp vs ...
- 基于C语言的泛类型循环队列
循环队列多用于通信数据缓存中,尤其是在双方设备接收数据与处理数据不同步的情况下,使用循环队列先缓存通信数据,然后按照时间戳数据出队作出相应的处理,是一种比较合适的做法,在嵌入式编程中亦是如此.使用循环 ...