1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【愚公系列】10月 .NET CORE工具案例-DeveloperSharp(数据库负载均衡)

【愚公系列】10月 .NET CORE工具案例-DeveloperSharp(数据库负载均衡)

时间:2022-01-28 18:37:12

相关推荐

【愚公系列】10月 .NET CORE工具案例-DeveloperSharp(数据库负载均衡)

🏆 作者简介,愚公搬代码

🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。

🏆《近期荣誉》:CSDN博客之星TOP2,华为云十佳博主等。

🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。

🏆🎉欢迎 👍点赞✍评论⭐收藏

文章目录

🚀前言🚀一、同种数据库负载均衡🔎1.前提准备🔎2.安装包🔎3.数据库负载均衡的核心器件🔎4.相关实体类🔎5.测试 🚀二、异种数据库负载均衡🔎1.前提准备🔎2.测试🦋2.1 第三方连接🦋2.2 本工具连接☀️2.1.1 查询☀️2.1.2 分页☀️2.1.3 增/删/改☀️2.1.4 输出参数☀️2.1.5 存储过程 🚀备注🚀感谢:给读者的一封信

🚀前言

数据库负载均衡指的是将数据库的请求分配到多个数据库服务器上,并通过一系列算法和策略来确保各个服务器的负载相对平衡。这样可以有效避免单个数据库服务器的过载,提高数据库的整体稳定性和性能。负载均衡器通常会监控服务器的负载情况以及数据库响应时间,根据不同的负载情况来动态调整请求的分配策略。常见的负载均衡算法包括轮询、随机、最少连接等。

本文主要介绍DeveloperSharp的使用,DeveloperSharp是一个研发中大型项目必备的系统平台,也是一个低代码平台。

它主要包括了如下一些功能:

基于Sql语句、存储过程、事务、分页的数据库操作。并几乎支持市面上所有种类的数据库。图片操作。裁剪、缩放、加水印。http请求调用(Post与Get)高效分页Web服务/WebApi的负载均衡数据库的负载均衡,以及读写分离CORS跨域访问UUID全球通用唯一识别码MQ消息队列(请另行使用DeveloperSharp.RabbitMQ包)Redis缓存(请另行使用DeveloperSharp.Redis包)“异种数据库”的负载均衡其他相关功能

🚀一、同种数据库负载均衡

🔎1.前提准备

先创建三个数据库,它们的名字分别为YG1、YG2、YG3,表结构如下

CREATE TABLE students (id INT IDENTITY(1,1) PRIMARY KEY,name VARCHAR(255) NOT NULL,age INT NOT NULL,gender VARCHAR(8) NOT NULL,major VARCHAR(255) NOT NULL,address VARCHAR(255) NOT NULL);

该表包含以下字段:

id:主键,自增长的学生ID。name:学生姓名,记录学生的姓名。age:学生年龄,记录学生的年龄。gender:学生性别,记录学生的性别。major:学生专业,记录学生的所学专业。address:学生地址,记录学生的地址。

对三张表分别插入数据

//----------------YG1insert into dbo.students (name, age, gender, major, address)values ('愚公1-1',30,'男','软件工程','福建省');insert into dbo.students (name, age, gender, major, address)values ('愚公2-1',30,'男','软件工程','福建省');insert into dbo.students (name, age, gender, major, address)values ('愚公3-1',30,'男','软件工程','福建省');//----------------YG2insert into dbo.students (name, age, gender, major, address)values ('愚公1-2',30,'男','软件工程','福建省');insert into dbo.students (name, age, gender, major, address)values ('愚公2-2',30,'男','软件工程','福建省');insert into dbo.students (name, age, gender, major, address)values ('愚公3-2',30,'男','软件工程','福建省');//----------------YG3insert into dbo.students (name, age, gender, major, address)values ('愚公1-3',30,'男','软件工程','福建省');insert into dbo.students (name, age, gender, major, address)values ('愚公2-3',30,'男','软件工程','福建省');insert into dbo.students (name, age, gender, major, address)values ('愚公3-3',30,'男','软件工程','福建省');

在.Net Core环境下,我们需要创建一个名为DeveloperSharp.json的配置文件,并在其中设置如上三个数据源的负载均衡策略。文件内容如下:

{"DeveloperSharp": {"DatabaseClusterList": [{"Id": "StudentData","DatabaseCluster": [{"Id": "A1","Enable": "true","Weight": "100","DatabaseType": "SqlServer","ConnectionString": "Server=localhost;Database=YG1;Uid=sa;Pwd=1"},{"Id": "A2","Enable": "true","Weight": "100","DatabaseType": "SqlServer","ConnectionString": "Server=localhost;Database=YG2;Uid=sa;Pwd=1"},{"Id": "A3","Enable": "true","Weight": "100","DatabaseType": "SqlServer","ConnectionString": "Server=localhost;Database=YG3;Uid=sa;Pwd=1"}]}]}}

对此配置文件说明如下:

每一个DatabaseCluster节点代表了一组数据库,此节点的Id值(本文示例值是:StudentData)后续会在程序中使用。

Database节点中的Weight属性代表了使用权重。本文示例的三个数据库的Weight值分别是100、100、100,则这三个数据库的负载均衡使用分配比例将会是1:1:1。若把这三个值分别设置为100、50、50,则这三个数据库的使用分配比例将会变为2:1:1。设置成你想要的比例吧。

Database节点中的Enable属性代表了是否可用。true代表可用,false代表不可用。

.Net6中可通过把DatabaseType属性的值设置为“MySql”、“SQLite”、“PostgreSql”、“Oracle”、其它等等,从而支持各种类数据库。

🔎2.安装包

DeveloperSharpEntityFramework

🔎3.数据库负载均衡的核心器件

//这个属性就是用作映射负载均衡。//其“值”需设置为前述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值。

🔎4.相关实体类

1、Entities类

public partial class Entities : DbContext{public Entities(): base("name=Entities"){}public Entities(string ConnectionString): base(ConnectionString){}protected override void OnModelCreating(DbModelBuilder modelBuilder){//throw new UnintentionalCodeFirstException();}public virtual DbSet<students> t_Student {get; set; }}

2、students类

public class students{public int id {get; set; }public string name {get; set; }public int age {get; set; }public string gender {get; set; }public string major {get; set; }public string address {get; set; }}

🔎5.测试

using ConsoleTest;string NameList = "";//第一次访问数据库var SLB = (new StudentLB()) as DeveloperSharp.Structure.Model.DataLayer;var db = new Entities(SLB.IDA.ConnectionString);//每次会根据配置的负载均衡策略输出对应的ConnectionStringstudents 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);//每次会根据配置的负载均衡策略输出对应的ConnectionStringStu = 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);//每次会根据配置的负载均衡策略输出对应的ConnectionStringStu = db.t_Student.Where(t => t.id == 3).FirstOrDefault();NameList += Stu.name;//输出Console.WriteLine(NameList);Console.ReadLine();

🚀二、异种数据库负载均衡

🔎1.前提准备

对比同种数据库,只需要修改配置文件DeveloperSharp.json,并在其中设置如上三个数据源的负载均衡策略。文件内容如下:

{"DeveloperSharp":{"DatabaseClusterList":[{"Id":"StudentData","DatabaseCluster":[{"Id":"A1","Enable":"true","Weight":"100","DatabaseType":"SqlServer","ConnectionString":"Server=localhost;Database=YG1;Uid=sa;Pwd=1"},{"Id":"A2","Enable":"true","Weight":"100","DatabaseType":"MySql","ConnectionString":"Host=localhost;Database=YG2;User Id=root;password=1"},{"Id":"A3","Enable":"true","Weight":"100","DatabaseType":"PostgreSql","ConnectionString":"Server=127.0.0.1;Database=YG3;Port=5432;User Id=postgres;Password=1;"}]}]}}

🔎2.测试

🦋2.1 第三方连接

重要的两个参数:

SLB.IDA.ConnectionString //数据库链接字符串SLB.IDA.DatabaseType //数据库类型

无论你的数据库访问工具是Entity Framework、Dapper、SqlSugar、FreeSql、等等,只要有了如上两个参数,你就能自行实现相应的数据库操作。

这种方式通知数据库中介绍了就不做多说

🦋2.2 本工具连接

using ConsoleTest;//第一次访问数据库var SLB = (new StudentLB()) as DeveloperSharp.Structure.Model.DataLayer;var IDA = SLB.IDA;//接下来,直接通过IDA进行各类数据库操作//查询多数据var Students1 = IDA.SqlExecute<students>("select * from students");foreach (students student in Students1){Console.WriteLine(student.name);}var Students2 = IDA.SqlExecute<students>("select * from students");foreach (students student in Students2){Console.WriteLine(student.name);}var Students3 = IDA.SqlExecute<students>("select * from students");foreach (students student in Students3){Console.WriteLine(student.name);}Console.ReadLine();

☀️2.1.1 查询

下面,首先直接给出一个“查询多数据+选出单数据+参数”的使用示例,代码如下:

//查询多数据var Students1 = IDA.SqlExecute<stu>("select * from t_Student");//查询多数据(带参数)var Students2 = IDA.SqlExecute<stu>("select * from t_Student where Id>@IdMin and Name like @LikeName", new {IdMin = 2, LikeName = "%周%" });//另一种写法1var IdMin = IDA.CreateParameterInput("IdMin", DbType.Int32, 2);var LikeName = IDA.CreateParameterInput("LikeName", DbType.String, 50, "%周%");var Students3 = IDA.SqlExecute<stu>("select * from t_Student where Id>@IdMin and Name like @LikeName", LikeName, IdMin);//另一种写法2var Students4 = IDA.SqlExecute<stu>("select * from t_Student").Where(t => t.Id > 2 && t.Name.Contains("周"));//选出单数据var OneStudent = Students2.FirstOrDefault();

其中stu实体类代码如下形式:

//此实体类中的Id、Name、Age、Birth、MyLevel属性名,要与数据表中的字段名一一对应public class stu{public int? Id {get; set; }//数据库中该字段若存在Null值,类型后需要加问号?public string Name {get; set; }public int? Age {get; set; }public DateTime? Birth {get; set; }public Level? MyLevel {get; set; }//也可以使用枚举,会自动转换}public enum Level{Student=100,//学生Teacher=200,//老师Manager=300,//管理员Principle=400//校长}

☀️2.1.2 分页

若我们要对Students1、Students2进行分页操作(比如:每页20条,取出第5页),相关代码如下:

using DeveloperSharp.Extension;//调用“分页功能”需要引用此命名空间--------------------------var Page1 = Students1.PagePartition(20, 5);var Page2 = Students2.PagePartition(20, 5);//一气呵成的写法var Page3 = IDA.SqlExecute<stu>("select * from t_Student").PagePartition(20, 5);

☀️2.1.3 增/删/改

下面是一个“修改数据+参数+事务”的使用示例:

try{//开启事务IDA.TransactionBegin();//修改数据(多语句)int affectedRows1 = IDA.SqlExecute("insert into t_Student(Name,Age)values('ww','96');update t_Student set Age=100 where Id=1006");//修改数据(带参数)int affectedRows2 = IDA.SqlExecute("insert into t_Student(Name,Age)values(@N,@A)", new {N = "孙悟空", A = 200 });//另一种写法var NewAge = IDA.CreateParameterInput("NewAge", DbType.Int32, 200);var NewName = IDA.CreateParameterInput("NewName", DbType.String, 50, "孙悟空");int affectedRows3 = IDA.SqlExecute("insert into t_Student(Name,Age)values(@NewName,@NewAge)", NewName, NewAge);//完成事务IDA.TransactionCommit();}catch{//回滚事务IDA.TransactionRollBack();}

☀️2.1.4 输出参数

示例代码如下:

var op1 = IDA.CreateParameterOutput("TotalCount", DbType.Int32);//此项为输出参数var op2 = IDA.CreateParameterOutput("MyName", DbType.String, 50);//此项为输出参数//以下sql语句混杂了多个“输入”与“输出”参数,注意看IDA.SqlExecute("insert into Friend(Birth,Name,height)values(@B,@N,@h);" +"select @TotalCount=count(*) from Friend;" +"select @MyName=Name from Friend where Id=@Id",new {N = "杨小伟", B = "1999-02-28 12:03:45", h = 11.023, Id = 2 },op1, op2);int tc = Convert.ToInt32(op1.Value);string mn = op2.Value.ToString();

☀️2.1.5 存储过程

我们创建一个存储过程,它带有输入、输出、返回三种类型的参数,代码如下:

CREATE PROCEDURE Test5@B as datetime,@N as nvarchar(50),@h as float,@TotalCount as int output,@MyName as nvarchar(50) output,@Id as intASBEGINinsert into Friend(Birth,Name,height)values(@B,@N,@h);select @TotalCount=count(*) from Friend;select @MyName=Name from Friend where Id=@Id;return @TotalCount+100;END

调用该存储过程的示例代码如下:

var op1 = IDA.CreateParameterOutput("TotalCount", DbType.Int32);//输出参数var op2 = IDA.CreateParameterOutput("MyName", DbType.String, 50);//输出参数var op3 = IDA.CreateParameterReturn();//返回参数IDA.SpExecute("Test5", new {N = "杨小伟", B = "1999-02-28 12:03:45", h = 11.023, Id = 2 }, op1, op2, op3);int tc = Convert.ToInt32(op1.Value);string mn = op2.Value.ToString();int ret = Convert.ToInt32(op3.Value);

🚀备注

IDA内功能方法详细说明(辅助参考):

SqlExecute<T> (异步为:SqlExecuteAsync<T>)声明:IEnumerable<T> SqlExecute<T>(string cmdText, params IDataParameter[] Params) where T : class, new()用途:执行Sql语句(Select类)参数:(1)string cmdText -- Sql语句(2)params IDataParameter[] Params -- 参数组返回:IEnumerable<T> -- 多数据结果集SqlExecute<T> (异步为:SqlExecuteAsync<T>)声明:IEnumerable<T> SqlExecute<T>(string cmdText, object InputParams, params IDataParameter[] Params) where T : class, new()用途:执行Sql语句(Select类)参数:(1)string cmdText -- Sql语句(2)object InputParams -- 输入参数对象(3)params IDataParameter[] Params -- 参数组返回:IEnumerable<T> -- 多数据结果集SqlExecute (异步为:SqlExecuteAsync)声明:int SqlExecute(string cmdText, params IDataParameter[] Params)用途:执行Sql语句(Insert/Update/Delete类)参数:(1)string cmdText -- Sql语句(2)params IDataParameter[] Params -- 参数组返回:int -- 受影响的行数SqlExecute (异步为:SqlExecuteAsync)声明:int SqlExecute(string cmdText, object InputParams, params IDataParameter[] Params)用途:执行Sql语句(Insert/Update/Delete类)参数:(1)string cmdText -- Sql语句(2)object InputParams -- 输入参数对象(3)params IDataParameter[] Params -- 参数组返回:int -- 受影响的行数SpExecute<T> (异步为:SpExecuteAsync<T>)声明:IEnumerable<T> SpExecute<T>(string cmdText, params IDataParameter[] Params) where T : class, new()用途:执行Sp存储过程(Select类)参数:(1)string cmdText -- Sp存储过程名(2)params IDataParameter[] Params -- 参数组返回:IEnumerable<T> -- 多数据结果集SpExecute<T> (异步为:SpExecuteAsync<T>)声明:IEnumerable<T> SpExecute<T>(string cmdText, object InputParams, params IDataParameter[] Params) where T : class, new()用途:执行Sp存储过程(Select类)参数:(1)string cmdText -- Sp存储过程名(2)object InputParams -- 输入参数对象(3)params IDataParameter[] Params -- 参数组返回:IEnumerable<T> -- 多数据结果集SpExecute (异步为:SpExecuteAsync)声明:int SpExecute(string cmdText, params IDataParameter[] Params)用途:执行Sp存储过程(Insert/Update/Delete类)参数:(1)string cmdText -- Sp存储过程名(2)params IDataParameter[] Params -- 参数组返回:int -- 受影响的行数SpExecute (异步为:SpExecuteAsync)声明:int SpExecute(string cmdText, object InputParams, params IDataParameter[] Params)用途:执行Sp存储过程(Insert/Update/Delete类)参数:(1)string cmdText -- Sp存储过程名(2)object InputParams -- 输入参数对象(3)params IDataParameter[] Params -- 参数组返回:int -- 受影响的行数

🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。