

统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务
从0到1搭备份接口:配置与基础准备
要搭备份接口,先得把“地基”打牢——我当时踩的第一个坑就是基础配置没做好,导致后面反复返工。首先说环境:我用的是ASP.NET Core 6(如果你用7或8也一样,核心逻辑差不多),得装三个NuGet包:Microsoft.EntityFrameworkCore(和数据库交互的基础包)、Microsoft.EntityFrameworkCore.SqlServer(SQL Server专属驱动,用MySQL或PostgreSQL的话换对应的包)、Microsoft.Extensions.Configuration.Json(读appsettings.json里的配置)。装包时一定要注意版本匹配——我之前手滑装了EF Core 7,结果和.NET 6不兼容,启动项目直接跳黄页,后来换成同版本才解决。
接下来是配置文件。你得在appsettings.json
里加两个关键项:
{
"ConnectionStrings": {
"DatabaseConn": "Server=localhost;Database=YourDB;User Id=sa;Password=YourPwd;"
},
"BackupSettings": {
"BackupPath": "D:\DBBackups", // 备份文件存储路径
"MaxBackupRetainDays": 7 // 备份文件保留7天
}
}
这里要注意两点:一是BackupPath对应的文件夹必须提前创建,比如D:\DBBackups
,不然接口会报“路径不存在”;二是应用程序池的账号要有文件夹写权限——我当时没给权限,接口返回“备份成功”,却找不到文件,查了半小时日志才发现是IIS的DefaultAppPool账号没有写权限,给权限后立刻好了。
还有安全问题:备份接口不能随便让人调用,最好加个JWT身份验证。我当时在Program.cs
里加了这段代码:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "YourIssuer",
ValidAudience = "YourAudience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey"))
};
});
然后在备份接口的Controller上加[Authorize]
属性,这样只有带有效Token的请求才能调用——朋友的系统之前被人扫到过接口,加了验证后再也没出现过非法调用。
核心逻辑实现:API怎么调用数据库备份
基础配置搞定,接下来就是写接口和备份逻辑了——这部分是核心,我当时改了三版才达到稳定。首先建个BackupController
,写一个Post接口(按RESTful风格,修改操作要用Post):
[ApiController]
[Route("api/[controller]")]
[Authorize] // 启用身份验证
public class BackupController ControllerBase {
private readonly IConfiguration _config;
private readonly ILogger _logger;
public BackupController(IConfiguration config, ILogger logger) {
_config = config;
_logger = logger;
}
[HttpPost]
public async Task BackupDatabase([FromBody] BackupRequest request) {
// 备份逻辑写在这里
}
}
// 接收参数的类
public class BackupRequest {
public string DatabaseName { get; set; } // 要备份的数据库名
public string FileNamePrefix { get; set; } // 备份文件前缀(比如"OrderDB_")
}
参数用BackupRequest
类封装,这样可以灵活传数据库名和文件名前缀——比如朋友的系统有两个数据库,一个订单库一个用户库,用这个类就能分别备份。
接下来是备份的核心代码——我用的是SQL Server,所以执行BACKUP DATABASE
语句(其他数据库看下面的表格)。这里要注意异步执行,避免接口阻塞:
var backupPath = _config["BackupSettings:BackupPath"];
var connStr = _config.GetConnectionString("DatabaseConn");
var backupFileName = $"{request.FileNamePrefix}_{DateTime.Now:yyyyMMddHHmmss}.bak";
var fullBackupPath = Path.Combine(backupPath, backupFileName);
try {
_logger.LogInformation($"开始备份数据库:{request.DatabaseName},备份路径:{fullBackupPath}");
using (var conn = new SqlConnection(connStr)) {
await conn.OpenAsync();
var cmd = new SqlCommand();
cmd.Connection = conn;
// WITH INIT表示覆盖现有文件,若要追加用WITH NOINIT
cmd.CommandText = $"BACKUP DATABASE [{request.DatabaseName}] TO DISK = @backupPath WITH INIT";
cmd.Parameters.AddWithValue("@backupPath", fullBackupPath);
await cmd.ExecuteNonQueryAsync();
}
_logger.LogInformation($"数据库备份成功:{request.DatabaseName},文件路径:{fullBackupPath}");
return Ok(new { Message = "备份成功", BackupFile = fullBackupPath });
} catch (Exception ex) {
_logger.LogError(ex, $"备份数据库失败:{request.DatabaseName}");
return StatusCode(500, new { Message = "备份失败", Error = ex.Message });
}
我之前犯过一个错:直接把数据库名拼进SQL语句里,结果遇到带特殊字符的数据库名(比如“Order_DB-2024”),直接报语法错误——后来改用参数化查询(@backupPath
),就解决了这个问题。
下面这个表格是我整理的常用数据库备份语句对比,你可以对照着改:
数据库类型 | 备份语句示例 | 关键注意事项 |
---|---|---|
SQL Server | BACKUP DATABASE [TestDB] TO DISK = ‘D:BackupsTestDB_20240520.bak’ WITH INIT; | 需要数据库排他访问,若有长查询需先终止 |
MySQL | mysqldump -u root -p TestDB > D:BackupsTestDB_20240520.sql | 需安装mysqldump工具, 设置PGPASSWORD免密 |
PostgreSQL | pg_dump -U postgres TestDB > D:BackupsTestDB_20240520.sql | 注意用户权限,需有数据库备份权限 |
避坑与优化:让备份更稳定的细节
我搭完接口的第一个月,遇到两个“隐形坑”:一是备份大数据库时接口超时,二是备份文件越积越多占满硬盘。后来改了几个细节,才让接口真正“能用且稳定”。
首先是超时问题。ASP.NET Core默认请求超时是100秒,要是你备份的数据库有几十个G,肯定不够用。我在Program.cs
里加了这段配置,把超时时间改成5分钟:
builder.WebHost.ConfigureKestrel(options => {
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(5);
options.Limits.MaxRequestBodySize = null; // 取消请求大小限制
});
改完后,备份100G的数据库也没再超时——朋友的系统有个历史数据库,之前备份要4分20秒,改了超时后一次过。
然后是日志记录。一定要把备份的每一步都记下来,不然出问题根本没法查。我用Serilog配置了文件日志+控制台日志,日志文件存在D:LogBackupLog
,每天一个文件,格式是yyyyMMdd_backup.log
。比如备份失败时,日志会显示:“2024-05-20 14:30:00 [Error] 备份数据库失败:OrderDB,错误信息:数据库正在被使用,无法获取排他访问权”——看到这条我就知道,是有个长查询没关,关了再备份就好了。
还有备份文件清理。备份文件存多了占空间,我用Hangfire(.NET的定时任务框架)加了个每日清理任务:每天凌晨3点,删除7天前的备份文件。代码很简单:
// 启动Hangfire
builder.Services.AddHangfire(config => config.UseSqlServerStorage(connStr));
builder.Services.AddHangfireServer();
// 添加定时任务
var app = builder.Build();
app.UseHangfireDashboard();
RecurringJob.AddOrUpdate("DeleteOldBackups", () => DeleteOldBackups(), Cron.Daily(3)); // 每天3点执行
// 清理方法
public void DeleteOldBackups() {
var backupPath = _config["BackupSettings:BackupPath"];
var maxRetainDays = int.Parse(_config["BackupSettings:MaxBackupRetainDays"]);
var files = Directory.GetFiles(backupPath);
foreach (var file in files) {
var fileInfo = new FileInfo(file);
if (fileInfo.CreationTime < DateTime.Now.AddDays(-maxRetainDays)) {
fileInfo.Delete();
_logger.LogInformation($"删除旧备份文件:{file}");
}
}
}
朋友的系统现在每天生成3个备份文件,7天后自动删除,再也不用手动删文件,省了不少事。
我帮朋友搭的这个备份接口,现在已经跑了快一年,没出过大问题——他说比之前手动备份省心10倍。你要是按上面的步骤做,肯定能搞定——对了,要是遇到问题,比如配置文件读不出来,或者接口调用报错,欢迎在评论区留消息,我帮你看看。或者你有更好的优化方法,也可以告诉我,咱们互相学习!
ASP.NET Core版本和EF Core版本不匹配怎么办?
我之前就踩过这个坑——手滑装了EF Core 7,结果和.NET 6不兼容,启动项目直接跳黄页。后来换成和ASP.NET Core同版本的EF Core才解决。比如你用.NET 6,就装EF Core 6;用.NET 7或8,就装对应版本的EF Core,核心逻辑都差不多,版本匹配最重要。
appsettings.json里的BackupPath要注意什么?
BackupPath对应的文件夹得提前创建,比如你写D:\DBBackups,就要先在D盘建这个文件夹,不然接口会报“路径不存在”。 应用程序池的账号得有文件夹写权限——我之前没给权限,接口返回“备份成功”却找不到文件,查了半小时日志才发现是IIS的DefaultAppPool账号没权限,给了权限就好了。
备份数据库时直接拼SQL语句为什么会报错?
我之前犯过这个错,直接把数据库名拼进SQL语句,结果遇到带特殊字符的数据库名(比如“Order_DB-2024”),直接报语法错误。后来改用参数化查询就解决了,比如用@backupPath代替直接拼路径,这样不管数据库名有没有特殊字符都不会出错。
备份大数据库时接口超时怎么处理?
ASP.NET Core默认请求超时是100秒,要是备份几十个G的数据库肯定不够用。我在Program.cs里改了Kestrel的配置,把超时时间改成5分钟,还取消了请求大小限制——改完后,备份100G的数据库也没再超时,朋友的历史数据库备份要4分20秒,现在一次过。
备份文件越积越多怎么自动清理?
我用Hangfire加了个每日清理任务,每天凌晨3点删除7天前的备份文件。首先装Hangfire的包,用SQL Server存储任务,然后加个RecurringJob调用DeleteOldBackups方法——现在朋友的系统每天自动删旧文件,再也不用手动清理,省了不少事。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com