# DMS分页功能实现文档 ## 概述 为了解决当待测试的节点数量非常多时出现的内存溢出问题,我们实现了DMS API的分页获取功能。原来的实现一次性获取所有数据(pageSize=100000),现在改为分页获取,大大减少了内存使用。 ## 问题背景 ### 原始问题 ``` MemoryError ``` ### 原因分析 - 原代码使用 `pageSize=100000` 一次性获取所有API数据 - 当API数量很大时,会导致内存溢出 - JSON序列化大量数据时也会消耗大量内存 ## 解决方案 ### 1. 分页获取API列表 **修改文件**: `ddms_compliance_suite/input_parser/parser.py` **主要改进**: - 添加 `page_size` 参数(默认1000) - 实现循环分页获取逻辑 - 收集并返回分页统计信息 ```python def parse_dms_spec(self, domain_mapping_path: str, base_url: str, headers: Optional[Dict[str, str]] = None, ignore_ssl: bool = False, page_size: int = 1000) -> Optional[Tuple[ParsedDMSSpec, Dict[str, Any]]]: ``` **分页逻辑**: ```python while True: list_url = urljoin(base_url, f"/api/schema/manage/schema?pageNo={page_no}&pageSize={page_size}") # 获取当前页数据 # 检查是否还有更多页面 # 更新分页统计信息 ``` ### 2. 分页信息收集 **返回的分页信息**: ```json { "page_size": 1000, "total_pages": 15, "total_records": 14523, "pages_fetched": 15 } ``` ### 3. 命令行支持 **修改文件**: `run_api_tests.py` **新增参数**: ```bash --page-size 1000 # DMS API分页大小,默认1000 ``` **使用示例**: ```bash python run_api_tests.py \ --dms ./assets/doc/dms/domain.json \ --base-url https://www.dev.ideas.cnpc \ --page-size 500 \ --ignore-ssl ``` ### 4. API服务器支持 **修改文件**: `api_server.py` **配置参数**: ```json { "dms": "./assets/doc/dms/domain.json", "base-url": "https://www.dev.ideas.cnpc", "page-size": 500, "ignore-ssl": true } ``` **响应格式**: ```json { "status": "completed", "message": "Tests finished.", "report_directory": "/path/to/reports", "summary": { ... }, "pagination": { "page_size": 500, "total_pages": 30, "total_records": 14523, "pages_fetched": 30 } } ``` ## 性能优化 ### 内存使用对比 | 分页大小 | 估算内存使用 | 请求次数 | 推荐场景 | |---------|-------------|---------|----------| | 100 | ~10MB | 多 | 内存受限环境 | | 500 | ~50MB | 中等 | 平衡选择 | | 1000 | ~100MB | 较少 | 默认推荐 | | 5000 | ~500MB | 很少 | 高性能环境 | ### 建议配置 **开发环境**: ```bash --page-size 100 # 快速测试,减少内存使用 ``` **测试环境**: ```bash --page-size 500 # 平衡性能和内存 ``` **生产环境**: ```bash --page-size 1000 # 默认配置,性能最优 ``` ## 安全特性 ### 防护机制 1. **最大页数限制**: 防止无限循环 ```python if page_no > 1000: # 最多1000页 logger.warning("Reached maximum page limit (1000), stopping pagination") break ``` 2. **空页面检测**: 自动停止分页 ```python if not page_records: logger.info(f"No more records found on page {page_no}, stopping pagination") break ``` 3. **错误处理**: 网络异常时的优雅降级 ```python except requests.exceptions.RequestException as e: self.logger.error(f"Failed to fetch API list from DMS: {e}") return None, {} ``` ## 向后兼容性 - 所有现有的调用方式仍然有效 - `page_size` 参数是可选的,默认值为1000 - 不使用分页信息的代码不受影响 ## 测试 ### 测试脚本 ```bash python test_pagination.py # 基本分页测试 python test_pagination.py --api-server # API服务器集成测试 ``` ### 验证要点 1. 分页获取的总记录数与一次性获取相同 2. 内存使用显著降低 3. 分页信息准确反映获取状态 4. 网络异常时能正确处理 ## 监控和日志 ### 日志输出示例 ``` [INFO] Fetching API list with pagination (page_size=1000) [INFO] Fetched 1000 records from page 1, total: 1000 [INFO] Fetched 1000 records from page 2, total: 2000 [INFO] Fetched 523 records from page 15, total: 14523 [INFO] Reached end of data. Total records: 14523 [INFO] DMS分页信息: 总记录数=14523, 页面大小=1000, 获取页数=15/15 ``` ### 性能指标 - 总记录数 - 分页大小 - 获取页数 - 估算内存使用 - 网络请求次数 ## 故障排除 ### 常见问题 1. **内存仍然不足** - 减小 `page_size` 值(如100或50) - 检查其他内存消耗源 2. **网络超时** - 增加请求超时时间 - 检查网络连接稳定性 3. **分页信息不准确** - 检查DMS API响应格式 - 验证 `total` 字段的准确性 ### 调试技巧 ```bash # 启用详细日志 python run_api_tests.py --dms ... --verbose # 使用小分页测试 python run_api_tests.py --dms ... --page-size 10 ``` ## 未来改进 1. **并行分页**: 同时获取多个页面 2. **缓存机制**: 缓存已获取的页面数据 3. **断点续传**: 支持从中断点继续获取 4. **压缩传输**: 减少网络传输数据量