跳到主要内容
版本:Next

故障排查与运维监控

简介

本故障排查与运维监控指南基于CMS Plugin框架的实际实现,重点介绍如何通过日志记录和监控机制快速定位和解决插件运行过程中的各种问题。该指南涵盖了部署失败、数据库迁移异常、后台任务执行错误等常见问题的诊断和解决方案。

日志系统架构

日志记录层次结构

日志配置最佳实践

根据项目中的实际实现,以下是推荐的日志配置:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"CMS.Plugin.MyPluginName": "Debug"
},
"Console": {
"FormatterName": "simple",
"FormatterOptions": {
"TimestampFormat": "yyyy-MM-dd HH:mm:ss.fff ",
"IncludeScopes": true
}
},
"File": {
"Path": "logs/myplugin-{Date}.log",
"FileSizeLimitBytes": 10485760,
"MaxRollingFiles": 10
}
}
}

常见故障类型与诊断

1. 数据库连接故障

故障特征

  • 插件启动时无法连接数据库
  • 运行过程中出现连接超时
  • EF Core迁移失败

诊断步骤

解决方案

  1. 验证连接字符串
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyPluginDB;User Id=myuser;Password=mypassword;"
}
}
  1. 测试数据库连接
# MySQL
mysql -h localhost -u myuser -pMyPluginDB

# SQL Server
sqlcmd -S localhost -U myuser -P password -d MyPluginDB

# PostgreSQL
psql -h localhost -U myuser -d MyPluginDB

2. 依赖注入失败

故障特征

  • 服务解析失败
  • 构造函数注入异常
  • 服务生命周期不匹配

诊断方法

3. EF Core迁移冲突

故障特征

  • 迁移历史表损坏
  • 版本冲突
  • 数据库架构不一致

解决方案

  1. 检查迁移历史
-- MySQL
SELECT * FROM __EFMigrationsHistory ORDER BY MigrationId;

-- SQL Server
SELECT * FROM dbo.__EFMigrationsHistory ORDER BY MigrationId;

-- PostgreSQL
SELECT * FROM public."__EFMigrationsHistory" ORDER BY "MigrationId";
  1. 手动清理迁移历史
# 删除特定迁移
dotnet ef migrations remove --project CMS.Plugin.MyPluginName.EntityFrameworkCore

# 重新生成初始迁移
dotnet ef migrations add InitialCreate --project CMS.Plugin.MyPluginName.EntityFrameworkCore

数据库迁移故障排查

迁移流程监控

迁移失败诊断

1. 日志分析

根据项目中的实现,迁移失败的日志记录如下:

// 成功日志
logger.LogInformation($"Start {project.Info.Id} MyPluginName dbcontext create");

// 失败日志
logger.LogError(ex, "Create MyPluginName db failed");

2. 常见迁移问题

问题类型错误信息解决方案
权限不足"Access denied"检查数据库用户权限
连接超时"Timeout expired"增加连接超时时间
表已存在"Table already exists"清理迁移历史或重命名表
字段冲突"Column already exists"手动删除字段或调整迁移

后台任务监控

MyPluginNameWorker监控

监控指标

  1. 执行频率监控
// 当前配置:每300秒执行一次
Timer.Period = 1 * 300 * 1000;
Timer.RunOnStart = true;
  1. 执行状态跟踪
_logger.LogInformation($"MyPluginNameWorker is working for project {project.Info.Id}");

性能优化建议

  1. 调整执行间隔
{
"MyPluginName": {
"WorkerIntervalSeconds": 600 // 从300秒增加到600秒
}
}
  1. 添加健康检查
public async Task<bool> HealthCheckAsync()
{
try
{
var project = await projectAccessor.GetProjectAsync();
return project != null && project.Info != null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Health check failed");
return false;
}
}

MyPluginNameJob监控

Job执行监控

  1. 日志记录模式
_logger.LogInformation($"MyPluginNameJob Execute,Subject={args.Subject},Body={args.Body},Count={count}");
  1. 性能指标
  • 执行时间:监控Job的平均执行时间
  • 失败率:统计Job的成功和失败比例
  • 资源使用:CPU和内存占用情况

性能监控指标

关键性能指标(KPI)

监控配置示例

1. 应用级监控

{
"Metrics": {
"Enabled": true,
"Endpoints": [
{
"Path": "/metrics",
"Port": 9090
}
],
"Collectors": {
"Default": true,
"AspNetCore": true,
"EntityFrameworkCore": true
}
}
}

2. 分布式追踪

{
"Tracing": {
"Enabled": true,
"Provider": "Jaeger",
"Endpoint": "http://localhost:14268/api/traces",
"SamplingRate": 0.1
}
}

告警规则配置

指标阈值告警级别处理建议
数据库连接失败率 > 5%警告中等检查数据库连接池配置
Worker执行时间 > 30秒警告优化Worker逻辑或增加资源
Job失败率 > 10%告警检查Job参数和依赖服务
内存使用率 > 80%告警中等检查内存泄漏或增加内存

生产环境配置建议

1. 日志配置优化

{
"Logging": {
"LogLevel": {
"Default": "Warning",
"CMS.Plugin.MyPluginName": "Information",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning"
},
"File": {
"Path": "/var/log/cms-plugin-myplugin/{Date}.log",
"FileSizeLimitBytes": 104857600,
"MaxRollingFiles": 20,
"RetainDays": 30
},
"Elasticsearch": {
"Uri": "http://elasticsearch:9200",
"IndexFormat": "cms-plugin-myplugin-{yyyy.MM.dd}"
}
}
}

2. 容器化部署配置

# docker-compose.yml
version: '3.8'
services:
myplugin:
image: cms-plugin-myplugin:latest
ports:
- "18000:18000"
volumes:
- ./logs:/var/log/cms-plugin-myplugin
- ./config:/app/config
environment:
- ASPNETCORE_ENVIRONMENT=Production
- DatabaseType=MySQL
- ConnectionStrings__Default=${DB_CONNECTION_STRING}
depends_on:
- mysql
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18000/health"]
interval: 30s
timeout: 10s
retries: 3

3. 监控仪表板配置

{
"dashboard": {
"title": "MyPlugin Monitoring",
"panels": [
{
"title": "Worker Execution Status",
"type": "stat",
"targets": [
{
"expr": "rate(myplugin_worker_executions_total[5m])",
"legendFormat": "Execution Rate"
}
]
},
{
"title": "Job Failure Rate",
"type": "graph",
"targets": [
{
"expr": "rate(myplugin_job_failures_total[5m])",
"legendFormat": "Failure Rate"
}
]
}
]
}
}

故障排除工具与技巧

1. 日志分析工具

a) 结构化日志查询

# 使用jq过滤JSON日志
cat logs/myplugin-*.log | jq '.Level == "Error"' | head -20

# 按时间范围筛选
cat logs/myplugin-2024-01-*.log | jq 'select(.Timestamp >= "2024-01-01T00:00:00Z" and .Timestamp <= "2024-01-31T23:59:59Z")'

# 统计错误类型
cat logs/myplugin-*.log | jq -r '.Message' | sort | uniq -c | sort -nr

b) 实时监控

# 实时查看错误日志
tail -f logs/myplugin-*.log | jq 'select(.Level == "Error")'

# 监控特定服务
tail -f logs/myplugin-*.log | jq 'select(.Category == "CMS.Plugin.MyPluginName.Workers.MyPluginNameWorker")'

2. 性能分析工具

a) .NET性能分析

# 使用dotnet-counters监控
dotnet-counters monitor --process-id 1234 --counters System.Runtime,CMS.Plugin.MyPluginName

# 使用dotnet-trace捕获性能数据
dotnet-trace collect --process-id 1234 --providers Microsoft.EntityFrameworkCore

b) 数据库性能监控

-- MySQL性能监控
SHOW FULL PROCESSLIST;
SHOW STATUS LIKE 'Threads_connected';
SHOW ENGINE INNODB STATUS;

-- SQL Server性能监控
SELECT * FROM sys.dm_exec_requests WHERE session_id > 50;
SELECT * FROM sys.dm_os_performance_counters WHERE counter_name LIKE '%Page life expectancy%';

-- PostgreSQL性能监控
SELECT * FROM pg_stat_activity WHERE state = 'active';
SELECT * FROM pg_stat_user_tables WHERE schemaname = 'public';

3. 故障诊断清单

启动阶段

  • 检查appsettings.json配置
  • 验证数据库连接字符串
  • 确认数据库服务可用性
  • 检查端口占用情况

运行阶段

  • 监控Worker执行状态
  • 检查Job队列积压
  • 观察内存使用趋势
  • 分析CPU使用峰值

维护阶段

  • 定期清理日志文件
  • 更新数据库迁移脚本
  • 优化慢查询语句
  • 调整缓存策略

4. 自动化故障恢复

// 示例:自动重启Worker
public class WorkerHealthMonitor
{
private readonly ILogger<WorkerHealthMonitor> _logger;
private readonly IBackgroundWorkerManager _workerManager;

public async Task MonitorAsync()
{
var workers = await _workerManager.GetWorkersAsync();
foreach (var worker in workers)
{
if (!await IsHealthyAsync(worker))
{
_logger.LogWarning("Worker {Name} is unhealthy, restarting...", worker.GetType().Name);
await RestartWorkerAsync(worker);
}
}
}

private async Task<bool> IsHealthyAsync(IBackgroundWorker worker)
{
// 实现健康检查逻辑
return true;
}

private async Task RestartWorkerAsync(IBackgroundWorker worker)
{
await _workerManager.RemoveAsync(worker);
await _workerManager.AddAsync(worker);
}
}

总结

本故障排查与运维监控指南提供了全面的故障诊断和监控解决方案。通过合理配置日志系统、监控关键性能指标、建立自动化故障检测机制,可以显著提高系统的稳定性和可维护性。

关键要点

  1. 日志系统:充分利用ILogger接口记录详细的运行信息,便于问题定位
  2. 监控体系:建立多层次的监控体系,包括应用层、数据库层和系统层
  3. 自动化运维:实现自动化的故障检测和恢复机制
  4. 配置管理:采用环境变量和配置中心管理敏感配置信息
  5. 持续改进:定期回顾和优化监控策略和故障处理流程

通过遵循本指南的最佳实践,可以构建一个健壮、可观察的CMS插件系统,确保在生产环境中稳定高效地运行。