diff --git a/src/Controllers/ManagementController.cs b/src/Controllers/ManagementController.cs
index 346e172..47e3268 100644
--- a/src/Controllers/ManagementController.cs
+++ b/src/Controllers/ManagementController.cs
@@ -358,5 +358,32 @@ namespace iFileProxy.Controllers
});
}
}
+
+ ///
+ /// 获取数据库连接池状态
+ ///
+ [HttpGet("GetConnectionPoolInfo")]
+ public async Task> GetConnectionPoolInfo()
+ {
+ try
+ {
+ var poolInfo = await _dbGateService.GetConnectionPoolInfoAsync();
+ return Ok(new CommonRsp
+ {
+ Retcode = 0,
+ Message = "success",
+ Data = poolInfo
+ });
+ }
+ catch (Exception ex)
+ {
+ _logger.Error($"获取连接池信息失败: {ex.Message}");
+ return Ok(new CommonRsp
+ {
+ Retcode = 1,
+ Message = "获取连接池信息失败"
+ });
+ }
+ }
}
}
diff --git a/src/Models/Db.cs b/src/Models/Db.cs
index 9be3a12..3b8a46e 100644
--- a/src/Models/Db.cs
+++ b/src/Models/Db.cs
@@ -106,4 +106,81 @@ namespace iFileProxy.Models
public static string iFileProxy = "iFileProxy_Db";
}
+
+ ///
+ /// 数据库连接池信息
+ ///
+ public class ConnectionPoolInfo
+ {
+ ///
+ /// 当前总连接数
+ ///
+ public long TotalConnections { get; set; }
+
+ ///
+ /// 活跃连接数
+ ///
+ public long ActiveConnections { get; set; }
+
+ ///
+ /// 空闲连接数
+ ///
+ public long SleepingConnections { get; set; }
+
+ ///
+ /// 连接池最大连接数
+ ///
+ public int MaxPoolSize { get; set; }
+
+ ///
+ /// 连接详情列表
+ ///
+ public List Connections { get; set; } = [];
+ }
+
+ ///
+ /// MySQL 进程列表信息
+ ///
+ public class ProcessListInfo
+ {
+ ///
+ /// 连接ID
+ ///
+ public long Id { get; set; }
+
+ ///
+ /// 用户名
+ ///
+ public string User { get; set; } = string.Empty;
+
+ ///
+ /// 主机信息
+ ///
+ public string Host { get; set; } = string.Empty;
+
+ ///
+ /// 数据库名
+ ///
+ public string Db { get; set; } = string.Empty;
+
+ ///
+ /// 命令类型
+ ///
+ public string Command { get; set; } = string.Empty;
+
+ ///
+ /// 执行时间(秒)
+ ///
+ public long Time { get; set; }
+
+ ///
+ /// 连接状态
+ ///
+ public string State { get; set; } = string.Empty;
+
+ ///
+ /// 执行的SQL
+ ///
+ public string Info { get; set; } = string.Empty;
+ }
}
diff --git a/src/Program.cs b/src/Program.cs
index babdb49..c941411 100644
--- a/src/Program.cs
+++ b/src/Program.cs
@@ -16,18 +16,18 @@ namespace iFileProxy
SerilogConfig.CreateLogger();
Serilog.ILogger logger = Log.Logger.ForContext();
- Console.Write(" "); // ǿ��֢�����ſ�ʼ��������־�����벻�þ�
+ Console.Write(" "); // 补全日志第一行开头的空白
var builder = WebApplication.CreateBuilder(args);
- // ���� CORS ����
+ // CORS配置
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowFrontend",
builder =>
{
builder
- .WithOrigins("http://localhost:3000", "http://admin.gitdl.cn", "https://admin.gitdl.cn","http://47.243.56.137:50050") // ǰ�˵�ַ
+ .WithOrigins("http://localhost:3000", "http://admin.gitdl.cn", "https://admin.gitdl.cn","http://47.243.56.137:50050")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
@@ -55,10 +55,9 @@ namespace iFileProxy
builder.Services.AddSingleton();
- // ������֤����
+ // 添加验证服务
builder.Services.AddScoped();
- // ����JWT��֤
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
@@ -77,9 +76,8 @@ namespace iFileProxy
var app = builder.Build();
- AppConfig.CheckAppConfig(app.Services);
-
- LocalCacheManager localCacheManager = new(app.Services);
+ // 全局错误处理中间件
+ app.UseMiddleware();
app.UseSerilogRequestLogging(options =>
{
@@ -98,17 +96,21 @@ namespace iFileProxy
app.UseSwaggerUI();
}
- // ��������
- app.UseMiddleware();
+ // 检查自定义配置
+ AppConfig.CheckAppConfig(app.Services);
+
+ // 初始化缓存管理器
+ LocalCacheManager localCacheManager = new(app.Services);
+
app.UseCors("AllowFrontend");
app.UseHttpsRedirection();
- // ����Ĭ���ļ�ѡ��
+
var defaultFilesOptions = new DefaultFilesOptions();
- defaultFilesOptions.DefaultFileNames.Clear(); // ���Ĭ���б�
- defaultFilesOptions.DefaultFileNames.Add("index.html"); // �����Զ���Ĭ���ļ�
+ defaultFilesOptions.DefaultFileNames.Clear();
+ defaultFilesOptions.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(defaultFilesOptions);
@@ -120,7 +122,7 @@ namespace iFileProxy
app.Services.GetRequiredService>>(),
AppConfig.GetCurrConfig().SecurityOptions.DailyRequestLimitPerIP);
- // ������
+ // JWT中间件
app.UseMiddleware();
app.MapControllers();
diff --git a/src/Services/DatabaseGateService.cs b/src/Services/DatabaseGateService.cs
index c9664b0..793a94c 100644
--- a/src/Services/DatabaseGateService.cs
+++ b/src/Services/DatabaseGateService.cs
@@ -115,11 +115,22 @@ namespace iFileProxy.Services
if (db_user == null || db_password == null || db_host == null || db_port == null)
throw new NoNullAllowedException("数据库配置获取失败,不允许为空的字段出现空值");
- string db_connstr = $"server={db_host};user={db_user};database={Db.DatabaseName};port={db_port};password={db_password};Pooling=true;MaximumPoolSize=500;";
- MySqlConnection conn;
+ var builder = new MySqlConnectionStringBuilder
+ {
+ Server = db_host,
+ UserID = db_user,
+ Database = Db.DatabaseName,
+ Port = (uint)db_port,
+ Password = db_password,
+ Pooling = true,
+ MinimumPoolSize = 1,
+ MaximumPoolSize = 50,
+ ConnectionLifeTime = 300 // 连接最大生命周期(秒)
+ };
+
try
{
- conn = new MySqlConnection(db_connstr);
+ var conn = new MySqlConnection(builder.ConnectionString);
conn.Open();
return conn;
}
@@ -900,5 +911,61 @@ namespace iFileProxy.Services
var users = await ExecuteQueryAsync(sql, parameters);
return users.FirstOrDefault();
}
+
+ ///
+ /// 获取数据库连接池状态
+ ///
+ /// 连接池信息
+ public async Task GetConnectionPoolInfoAsync()
+ {
+ try
+ {
+ var appName = "iFileProxy"; // 程序名称
+ var parameters = new Dictionary
+ {
+ { "@appName", $"%{appName}%" }
+ };
+
+ // 获取总连接数
+ var totalSql = @"SELECT COUNT(*)
+ FROM information_schema.processlist
+ WHERE info LIKE @appName OR host LIKE @appName";
+ var totalConnections = await ExecuteScalarAsync(totalSql, parameters);
+
+ // 获取活跃连接数
+ var activeSql = @"SELECT COUNT(*)
+ FROM information_schema.processlist
+ WHERE Command != 'Sleep'
+ AND (info LIKE @appName OR host LIKE @appName)";
+ var activeConnections = await ExecuteScalarAsync(activeSql, parameters);
+
+ // 获取睡眠连接数
+ var sleepingSql = @"SELECT COUNT(*)
+ FROM information_schema.processlist
+ WHERE Command = 'Sleep'
+ AND (info LIKE @appName OR host LIKE @appName)";
+ var sleepingConnections = await ExecuteScalarAsync(sleepingSql, parameters);
+
+ // 获取连接详情
+ var detailSql = @"SELECT id, user, host, db, command, time, state, info
+ FROM information_schema.processlist
+ WHERE info LIKE @appName OR host LIKE @appName";
+ var connections = await ExecuteQueryAsync(detailSql, parameters);
+
+ return new ConnectionPoolInfo
+ {
+ TotalConnections = totalConnections,
+ ActiveConnections = activeConnections,
+ SleepingConnections = sleepingConnections,
+ MaxPoolSize = 50, // 从配置中获取的最大连接数
+ Connections = connections
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.Error($"获取连接池信息失败: {ex.Message}");
+ throw;
+ }
+ }
}
}
diff --git a/src/Services/LocalCacheManager.cs b/src/Services/LocalCacheManager.cs
index aa44e43..8cb46af 100644
--- a/src/Services/LocalCacheManager.cs
+++ b/src/Services/LocalCacheManager.cs
@@ -39,7 +39,7 @@ namespace iFileProxy.Services
public void CheckAndCleanCache(object state)
{
// 初始化并打开一个MySQL连接 防止后续数据过多导致程序crush
- var dbConn = _dbGateService.GetAndOpenDBConn(DbConfigName.iFileProxy);
+ using var dbConn = _dbGateService.GetAndOpenDBConn(DbConfigName.iFileProxy);
// 获取数据库中超出生命周期的缓存数据
string result = _dbGateService.QueryTableData($"SELECT * FROM t_tasks_info WHERE UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(update_time) > {CACHE_LIFETIME} AND (tag <> 'CLEANED' OR tag IS NULL)", DbConfigName.iFileProxy);
@@ -67,6 +67,8 @@ namespace iFileProxy.Services
_dbGateService.UpdateTaskStatus(taskInfo,dbConn);
}
}
+
+
}
///