【朝夕教育】2023年10月 .NET CORE工具案例-DeveloperSharp(数据库负载均衡)

本文介绍了数据库负载均衡,可避免单个服务器过载,提高稳定性和性能。主要讲解了DeveloperSharp的使用,包括其多种功能。详细阐述了在.NET Core环境下,同种和异种数据库负载均衡的前提准备、安装包、核心器件、相关实体类及测试等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,优快云博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年优快云博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏


🚀前言

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

本文主要介绍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:学生地址,记录学生的地址。

在这里插入图片描述
对三张表分别插入数据

//----------------YG1
insert 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,'男','软件工程','福建省');
//----------------YG2
insert 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,'男','软件工程','福建省');
//----------------YG3
insert 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.安装包

DeveloperSharp
EntityFramework

在这里插入图片描述

🔎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);//每次会根据配置的负载均衡策略输出对应的ConnectionString
students 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();

在这里插入图片描述

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

🔎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 = "%周%" });
//另一种写法1
var 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);
//另一种写法2
var 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 int
AS
BEGIN
    insert 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元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

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

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

在这里插入图片描述

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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值