93 lines
2.9 KiB
Markdown
93 lines
2.9 KiB
Markdown
# 请求学生信息API.py 修复说明
|
||
|
||
## 问题描述
|
||
脚本执行30多分钟后报错:
|
||
- `(1053, 'Server shutdown in progress')` - MySQL服务器正在关闭
|
||
- `(2013, 'Lost connection to MySQL server during query')` - 连接丢失
|
||
|
||
## 根本原因
|
||
长时间运行的脚本,MySQL连接超时或断开,导致数据库操作失败。原代码没有:
|
||
1. 连接保活机制
|
||
2. 自动重连机制
|
||
3. 异常恢复能力
|
||
|
||
## 解决方案
|
||
|
||
### 1. 添加数据库连接管理
|
||
在`__init__`方法中添加:
|
||
```python
|
||
self._db_connection = None
|
||
self._last_ping_time = 0
|
||
self._ping_interval = 60 # 每60秒ping一次数据库
|
||
```
|
||
|
||
### 2. 实现连接池和保活机制
|
||
新增`_get_db_connection()`方法:
|
||
- 创建带超时配置的数据库连接
|
||
- 定期ping数据库保持连接活跃(每60秒)
|
||
- 自动检测并重连断开的连接
|
||
|
||
### 3. 实现重试机制
|
||
新增`_execute_with_retry()`方法:
|
||
- 捕获特定的连接错误(2013, 2006, 1053)
|
||
- 最多重试3次
|
||
- 递增等待时间(2秒、4秒、6秒)
|
||
|
||
### 4. 重构主要方法
|
||
|
||
#### `get_and_save_students_batch()`
|
||
- 使用`_execute_with_retry()`包装数据库操作
|
||
- 在批量提交时自动ping连接
|
||
- 统一的异常处理和资源释放
|
||
|
||
#### `sync_student_msg()`
|
||
- 使用`_execute_with_retry()`包装整个同步逻辑
|
||
- 确保连接断开时自动重试
|
||
|
||
#### `_insert_into_target()`
|
||
- 在每100条记录批量提交前ping连接
|
||
- 确保长时间运行时连接保持活跃
|
||
|
||
### 5. 改进错误处理
|
||
- 添加详细的错误堆栈信息(traceback)
|
||
- 失败时返回已保存的数量而不是0
|
||
- 更好的日志输出
|
||
|
||
## 主要改进点
|
||
|
||
| 改进项 | 说明 |
|
||
|--------|------|
|
||
| 连接超时配置 | connect_timeout=30, read_timeout=60, write_timeout=60 |
|
||
| 连接保活 | 每60秒自动ping数据库 |
|
||
| 自动重连 | 连接断开时自动重建连接 |
|
||
| 重试机制 | 遇到连接错误最多重试3次 |
|
||
| 批量提交优化 | 每批提交前ping连接 |
|
||
| 错误日志 | 添加完整的traceback信息 |
|
||
| 资源管理 | 使用finally确保连接关闭 |
|
||
|
||
## 使用建议
|
||
|
||
1. **运行前检查MySQL配置**:
|
||
- `wait_timeout` 和 `interactive_timeout` 建议设置为 28800(8小时)
|
||
- `max_allowed_packet` 建议设置足够大(如16M)
|
||
|
||
2. **监控日志**:
|
||
- 观察"创建新的数据库连接"消息
|
||
- 检查"连接ping失败"警告
|
||
- 注意重试次数和等待时间
|
||
|
||
3. **调整参数**(如需要):
|
||
- `_ping_interval`: 默认60秒,可根据MySQL的wait_timeout调整
|
||
- `max_retries`: 默认3次,可根据网络稳定性调整
|
||
- `batch_size`: 默认100条,可根据数据大小调整
|
||
|
||
## 测试建议
|
||
|
||
1. 运行脚本观察是否能正常完成
|
||
2. 检查日志中的连接管理信息
|
||
3. 验证数据完整性
|
||
4. 如果仍有问题,可以:
|
||
- 减小`batch_size`(如改为50)
|
||
- 减小`_ping_interval`(如改为30秒)
|
||
- 增加MySQL的`wait_timeout`值
|