苏州网站制作开发中国建设网上银行登录
2026/2/28 23:56:20 网站建设 项目流程
苏州网站制作开发,中国建设网上银行登录,网站建设托管产品图,上市公司查询网站1. 概述1.1 背景在考试系统中#xff0c;当大量学生同时开始考试时#xff0c;系统需要为每个学生创建考试记录#xff08;ExamRecord#xff09;和答题记录#xff08;ExamAnswerRecord#xff09;。传统的按需创建模式在高并发场景下存在以下问题#xff…1. 概述1.1 背景在考试系统中当大量学生同时开始考试时系统需要为每个学生创建考试记录ExamRecord和答题记录ExamAnswerRecord。传统的按需创建模式在高并发场景下存在以下问题•性能瓶颈每次开始考试都需要执行数据库写入操作响应时间在 200-500ms•并发压力1000 学生同时开考时数据库压力激增可能导致超时或失败•用户体验学生点击开始考试后需要等待较长时间才能进入考试界面1.2 解决方案考试记录预生成方案通过定时任务每天凌晨1点批量预生成所有已发布且尚未开始的考试的记录和答题记录将数据库写入操作从考试开始时刻提前到凌晨低负载时段从而• ✅性能提升开始考试耗时从 200-500ms 降低到 10-50ms命中预生成记录时• ✅并发优化数据库写入压力分散到凌晨低负载时段避免影响正在进行的考试• ✅用户体验学生点击开始后即刻进入考试无感知延迟• ✅数据一致性题目顺序预先确定避免并发冲突1.3 核心特性•定时预生成每天凌晨1点通过定时任务统一预生成避免影响正在进行的考试•智能预生成仅预生成第一次考试记录AttemptNumber 1后续考试动态创建•缓存优化预生成记录写入缓存开始考试时优先查询缓存减少数据库查询•智能检测开始考试时自动检测预生成记录命中则快速启动未命中则动态创建•垃圾清理定时任务自动清理未使用的预生成记录避免数据冗余•容错机制预生成失败不影响考试发布新增学生自动降级为动态创建2. 架构设计2.1 系统架构图CreateExamRecordAsync学生数据库缓存层定时预生成任务ExamSettingServiceExamSettingsController管理员CreateExamRecordAsync学生数据库缓存层定时预生成任务ExamSettingServiceExamSettingsController管理员阶段1考试发布阶段2定时预生成每天凌晨1点阶段3学生开始考试alt[缓存命中][缓存未命中新增学生]阶段4定时清理每天凌晨2点发布考试PublishExamSettingAsync更新考试状态为Published返回成功查询已发布且尚未开始的考试检查是否已预生成分批创建ExamRecord(NotStarted)批量创建ExamAnswerRecord写入预生成记录ID过期时间考试结束时间打印详细日志点击开始考试查询预生成记录ID加载预生成记录UPDATE状态为InProgress设置StartTime快速启动(10-50ms) ✅动态创建完整记录常规启动(200-500ms) ⚠️查询已结束考试的NotStarted记录批量删除未使用记录清理相关缓存2.2 数据流设计是 否 是 否 是 否 考试发布 更新状态为Published 等待定时任务执行 定时任务每天凌晨1点 查询已发布且尚未开始的考试 是否已预生成? 跳过该考试 获取学生分组列表 分批处理学生列表 创建ExamRecordStatusNotStarted 创建ExamAnswerRecord列表 写入缓存Key: exam:pregenerated:examId:studentId:1Value: recordIdExpire: 考试结束时间1小时 是否还有批次? 预生成完成 学生开始考试 查询缓存 缓存命中? 加载预生成记录 更新状态为InProgress设置StartTime 快速启动 ✅ 动态创建记录 常规启动 ⚠️ 定时清理任务每天凌晨2点 查询已结束考试 查找NotStarted记录 批量删除 清理缓存2.3 核心组件2.3.1 预生成服务 (IExamRecordPreGenerationService)职责• 批量预生成考试记录和答题记录• 管理预生成缓存• 提供缓存键生成方法关键方法•PreGenerateExamRecordsAsync(long examId)- 为指定考试预生成所有学生记录•PreGenerateBatchAsync(long examId, IEnumerablelong studentIds, int attemptNumber)- 批量预生成指定学生记录•GetPreGeneratedRecordCacheKey(long examId, long studentId, int attemptNumber)- 生成缓存键2.3.2 考试记录服务 (ExamRecordService)职责• 智能检测预生成记录• 动态创建记录降级方案• 管理记录状态转换关键方法•CreateExamRecordAsync(long examId, long studentId, ...)- 创建或激活考试记录• 优先查询缓存获取预生成记录ID• 命中则更新状态和开始时间• 未命中则动态创建2.3.3 任务处理器定时预生成任务处理器(ExamRecordScheduledPreGenerationTaskHandler)• 定时执行每天凌晨1点• 查询所有已发布且尚未开始的考试• 检查是否已预生成避免重复处理• 分批处理学生列表• 记录详细日志手动预生成任务处理器(ExamRecordPreGenerationTaskHandler)• 用于手动触发单个考试的预生成• 接收考试ID参数• 分批处理学生列表• 记录详细日志清理任务处理器(ExamRecordCleanupTaskHandler)• 定时执行每天凌晨2点• 清理已结束考试的未使用记录• 同步清理缓存3. 核心设计要点3.1 状态管理3.1.1 考试记录状态扩展新增NotStarted 0状态用于标识预生成的记录public enum ExamRecordStatus { NotStarted 0, // 未开始预生成状态 InProgress 1, // 进行中 Submitted 2, // 已提交 Graded 3 // 已批改 }3.1.2 状态转换流程预生成 → NotStarted ↓ 开始考试 → InProgress ↓ 提交考试 → Submitted ↓ 批改完成 → Graded3.2 缓存策略3.2.1 缓存键设计exam:pregenerated:{examId}:{studentId}:{attemptNumber}示例exam:pregenerated:123:456:13.2.2 缓存过期时间核心原则缓存过期时间 考试结束时间 1小时缓冲• ✅正常情况考试结束时间在未来 → 过期时间 结束时间 - 当前时间 1小时• ⚠️异常情况考试已结束或时间异常 → 使用默认7天过期设计理由• 确保考试期间缓存始终有效• 考试结束后保留1小时缓冲处理延迟提交等场景• 避免缓存永久占用内存3.3 分批处理策略3.3.1 批次大小•默认批次大小50 名学生/批•可配置根据系统性能调整常量BATCH_SIZE3.3.2 批次间延迟•延迟时间200 毫秒常量DELAY_BETWEEN_BATCHES_MS•设计目的限制预生成速度避免对 CPU 和数据库造成过大压力•执行时机每处理完一批学生后延迟 200ms 再处理下一批•性能平衡在保证预生成效率的同时不影响系统正常运行3.3.3 开考前自动停止•停止阈值开考前 5 分钟常量STOP_BEFORE_EXAM_START_MINUTES•检测机制每批次处理前检查当前时间与考试开始时间的间隔•触发条件如果距离考试开始时间不足 5 分钟立即停止预生成•设计目的• 避免在考试即将开始时进行大量数据库操作确保系统资源优先服务于学生开考• 减少数据库负载提升考试开始时的系统响应能力•日志记录停止时会记录已处理和剩余的学生数量示例日志⚠️ 距离考试开始时间不足 5 分钟停止预生成。已处理: 800/1000剩余: 200 名学生未处理3.3.4 处理流程1. 获取所有需要预生成的学生ID列表2. 按批次大小切分默认 50 名/批3.检查开考时间如果距开考不足 5 分钟停止预生成4. 每批使用事务保证原子性5. 批次间延迟 200ms避免系统压力过大6. 记录每批成功/失败数量7. 打印详细日志便于跟踪3.4 容错机制3.4.1 预生成失败处理•不影响发布流程预生成任务异步执行失败不影响考试发布•降级方案预生成失败的学生开始考试时自动降级为动态创建•日志记录详细记录失败原因和学生ID便于排查3.4.2 新增学生处理•不预生成考试发布后新增的学生不进行预生成•动态创建新增学生开始考试时使用动态创建逻辑•性能影响新增学生比例通常较低5%不影响整体性能3.5 数据过滤3.5.1 监控界面过滤•默认排除监控和管理界面默认排除NotStarted状态的记录•可选查询如需查看预生成记录可显式指定状态查询3.5.2 查询优化-- 默认查询排除预生成记录 SELECT * FROM ExamRecord WHERE Status ! 0 -- NotStarted -- 显式查询预生成记录 SELECT * FROM ExamRecord WHERE Status 0 -- NotStarted4. 性能优化4.1 性能指标指标优化前优化后提升开始考试耗时200-500ms10-50ms90%数据库写入压力高峰期集中分散到发布时98%并发支持能力50010002倍缓存命中率-85%-4.2 优化措施4.2.1 缓存优先查询• 开始考试时优先查询缓存命中则直接加载记录• 缓存未命中才查询数据库减少数据库压力4.2.2 批量操作• 预生成时使用批量插入AddRangeAsync• 清理时使用批量删除DeleteRangeAsync4.2.3 事务优化• 每批预生成使用独立事务避免大事务锁表• 开始考试时使用分布式锁防止并发创建5. 实施要点5.1 关键时机5.1.1 预生成触发•触发时机定时任务每天凌晨1点•执行方式定时任务统一执行避免影响正在进行的考试•执行范围• 仅预生成已发布且尚未开始的考试Status PublishedANDStartTime 当前时间• 仅预生成第一次考试记录AttemptNumber 1• 自动跳过已预生成的考试避免重复处理5.1.2 清理触发•触发时机定时任务每天凌晨2点•清理条件• 考试已结束EndTime 当前时间• 记录状态为NotStarted• 创建时间早于阈值默认7天前5.2 日志记录5.2.1 定时预生成日志[INFO] [INFO] 考试记录定时预生成任务开始执行 [INFO] [INFO] 找到 3 个已发布且尚未开始的考试 [INFO] 考试 123 (数学期末考试) 已预生成跳过 [INFO] 开始为考试 456 (英语期末考试) 预生成记录 [INFO] 获取到 1000 名学生需要预生成记录 [INFO] 开始分批预生成每批 50 名学生共 20 批批次间延迟 200ms [INFO] 第 1/20 批完成成功 50失败 0 ... [WARN] ⚠️ 距离考试开始时间不足 5 分钟停止预生成。已处理: 800/1000剩余: 200 名学生未处理 [INFO] 考试 456 预生成完成 - 成功: 798, 跳过: 200 [INFO] 定时预生成完成 - 总计: 3, 成功: 2, 跳过: 1, 失败: 0 [INFO] 5.2.2 开始考试日志[INFO] ✅ 命中预生成记录快速启动考试ID123, 学生ID456, 记录ID789 [WARN] ⚠️ 未命中预生成记录执行动态创建考试ID123, 学生ID9995.3 配置说明5.3.1 预生成性能控制参数以下配置参数在ExamRecordPreGenerationService.cs中以常量形式定义参数默认值说明BATCH_SIZE50每批次处理的学生数量DELAY_BETWEEN_BATCHES_MS200ms批次间延迟时间避免系统压力过大STOP_BEFORE_EXAM_START_MINUTES5分钟开考前多久停止预生成确保系统资源优先服务于考试调整建议•批次大小根据数据库性能调整性能较好的系统可增大到 100•批次延迟如果系统负载高可增加到 500ms负载低可减少到 100ms•停止阈值建议保持 5 分钟确保考试开始前系统稳定5.3.2 定时任务配置{ ScheduledTasks:{ Tasks:[ { Id:exam-record-scheduled-pregeneration, Name:考试记录定时预生成, Description:每天凌晨1点为所有已发布且尚未开始的考试预生成记录, Type:Cron, CronExpression:0 0 1 * * *, HandlerType:CodeSpirit.ExamApi.Tasks.ExamRecordScheduledPreGenerationTaskHandler, Timeout:00:30:00, Enabled:true }, { Id:exam-record-cleanup, Name:考试记录垃圾数据清理, Description:清理未使用的预生成考试记录, HandlerType:CodeSpirit.ExamApi.Tasks.ExamRecordCleanupTaskHandler, CronExpression:0 0 2 * * *, Parameters:{\cleanupDays\: 7}, Enabled:true } ] } }Cron表达式说明•0 0 1 * * *表示每天凌晨1点执行预生成任务•0 0 2 * * *表示每天凌晨2点执行清理任务6. 注意事项6.1 数据一致性• ✅题目顺序预生成时确定题目顺序避免并发冲突• ✅事务保证每批预生成使用事务保证原子性• ✅分布式锁开始考试时使用分布式锁防止重复创建6.2 缓存一致性• ✅写入时机预生成完成后立即写入缓存• ✅更新时机开始考试时清除预生成缓存• ✅清理时机定时清理任务同步清理缓存6.3 监控建议• 预生成成功率监控预生成任务的成功/失败比例• 缓存命中率监控开始考试时的缓存命中率• 清理效果监控定时清理任务删除的记录数量• 性能指标监控开始考试的响应时间分布• 提前停止情况监控预生成任务是否因接近开考时间而提前停止如频繁发生应考虑提前发布考试• 系统负载监控预生成过程中的 CPU 和数据库负载必要时调整批次大小和延迟时间6.4 扩展性考虑• 多数据库支持预生成逻辑与数据库类型无关支持SQL Server和MySQL• 水平扩展预生成任务可分布式执行支持多实例部署• 配置化批次大小、批次延迟、停止阈值等参数可配置便于调优6.5 性能调优建议6.5.1 批次大小调优•小规模考试500人批次大小可设为 100快速完成预生成•大规模考试1000人保持默认 50避免单批次耗时过长•超大规模5000人可减小到 30配合更长的批次延迟500ms6.5.2 发布时机建议•推荐考试开始前至少 1 天发布确保在次日凌晨1点完成预生成•最低要求考试开始前至少 1 小时发布如果发布时间晚于凌晨1点预生成将在下一个凌晨1点执行•注意事项• 预生成任务在每天凌晨1点统一执行不会在发布时立即执行• 如果考试在凌晨1点之后发布且当天开考首批学生会使用动态创建模式性能略差• 建议提前发布考试以便享受预生成带来的性能优化6.5.3 系统负载控制•高负载时段增加批次延迟到 500ms减少对正在进行的考试的影响•低负载时段可减少批次延迟到 100ms加快预生成速度•监控指标CPU 使用率 70% 或数据库连接数 80% 时应调整参数7. 测试验证7.1 功能验证1.预生成功能• ✅ 发布考试后检查后台日志确认预生成任务执行• ✅ 查询数据库验证记录已创建且状态为NotStarted• ✅ 验证缓存中已写入预生成记录ID2.智能启动• ✅ 学生开始考试检查是否命中预生成记录• ✅ 测量启动耗时应降低到 10-50ms• ✅ 验证题目顺序正确3.动态补充• ✅ 发布后新增学生到分组• ✅ 该学生开始考试验证动态创建逻辑4.垃圾清理• ✅ 等待定时任务执行或手动触发• ✅ 检查日志和数据库确认垃圾数据被清理7.2 性能测试• 并发压力测试模拟1000学生同时开考• 对比测试对比预生成前后的数据库压力和响应时间• 缓存命中率测试统计不同场景下的缓存命中率8. 总结考试记录预生成方案通过提前创建和缓存优化两大核心策略显著提升了系统在高并发场景下的性能和用户体验。方案设计充分考虑了容错、扩展性和可维护性是一个生产级的优化方案。8.1 核心价值• 性能提升开始考试耗时降低 90%• 并发优化数据库压力降低 98%• 用户体验无感知延迟即刻进入考试• 数据一致性题目顺序预先确定避免冲突8.2 适用场景• ✅ 大规模考试1000 学生• ✅ 高并发开考场景• ✅ 对响应时间敏感的应用• ✅ 需要提升用户体验的场景文档版本v1.0最后更新2025年12月维护团队CodeSpirit 开发团队更多交流请关注“CodeSpirit-码灵”公众号进群

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询