432 lines
12 KiB
Markdown
432 lines
12 KiB
Markdown
# 13 domainCheck Linux 测试服交接文档
|
||
|
||
## 一、文档目的
|
||
|
||
本文档用于把当前 `domainCheck` 项目的 Linux 测试服联调状态,完整交接给后续接手的开发、运维或 Linux 上的 Codex。
|
||
|
||
目标是回答 4 个问题:
|
||
|
||
1. 当前到底完成到了什么程度
|
||
2. 这次 Linux 测试服已经验证通过了哪些内容
|
||
3. 还有哪些事情没有做完
|
||
4. 后续继续收口时,应该按什么顺序做
|
||
|
||
## 二、当前结论
|
||
|
||
当前项目状态可以明确分成两部分:
|
||
|
||
### 1. 已完成
|
||
|
||
- 本地 Windows 开发与联调已完成
|
||
- `domain-api` 与 `domain-web` 已完成主要功能开发
|
||
- Web/API 本地整栈自测已通过
|
||
- 交付包、验包、SHA256、最新交付指针已完成
|
||
- Linux 测试服数据库初始化问题已定位并修复
|
||
- Linux 测试服在“临时 API 进程 + 已初始化数据库”的模式下,`smoke test` 已通过
|
||
- Linux 测试服已经完成正式 `systemd` 服务化联调,`domaincheck-api` 与 `domaincheck-worker` 均已拉起
|
||
- 正式服务态下 `/health` 已确认 `worker_mode = linux-systemd`
|
||
- 正式服务态 `smoke test` 已通过
|
||
- 已补做一轮真实导入回归,确认“导入域名 -> 写入 `domains` -> 自动创建 `detect_tasks`”链路正常
|
||
|
||
### 2. 未完全完成
|
||
|
||
- Linux 测试服虽然已完成正式服务化联调,但仍属于“测试服验证通过”,不等于生产观察期已经完成
|
||
- Worker 当前通过 `QT_QPA_PLATFORM=offscreen` 运行,属于“无头 Qt 托管态”,后续仍建议继续观察稳定性
|
||
- 真实业务网络环境下的长时检测、代理池质量、Wayback 首次全量列表耗时,还需要继续压测和观察
|
||
- 当前数据库里仅导入了少量回归样本,不代表真实大批量数据已完成验收
|
||
|
||
一句话结论:
|
||
|
||
> 功能、数据库和正式服务化都已经打通;后续工作转入真实业务回归、稳定性观察和上线前优化。
|
||
|
||
## 三、这次 Linux 测试服已验证通过的内容
|
||
|
||
### 1. 数据库初始化问题已确认根因
|
||
|
||
本次 Linux 测试服最初失败的根因是:
|
||
|
||
- PostgreSQL 可连接
|
||
- 但业务库是空库
|
||
- 缺少 `domains` 等核心表
|
||
- 导致这些 API 因 `psycopg2.errors.UndefinedTable` 直接 `500`
|
||
|
||
受影响接口至少包括:
|
||
|
||
- `/api/v1/dashboard/overview`
|
||
- `/api/v1/detect/status`
|
||
- `/api/v1/imports/summary`
|
||
|
||
### 2. 正确修复方式已确认
|
||
|
||
在 Linux 测试服执行:
|
||
|
||
```bash
|
||
cd /www/wwwroot/getDomain/domainCheck
|
||
python init_database.py
|
||
```
|
||
|
||
执行后,核心业务表已成功创建/补齐:
|
||
|
||
- `domains`
|
||
- `detect_tasks`
|
||
- `domain_blacklist`
|
||
- `sensitive_words`
|
||
- `domain_detections`
|
||
|
||
数据库核查结果为:
|
||
|
||
- `table_count = 5`
|
||
- `domains_count = 0`
|
||
|
||
说明:
|
||
|
||
- 库结构已正常
|
||
- 只是当前还没有正式业务数据导入
|
||
|
||
### 3. 临时验证态 smoke test 已通过
|
||
|
||
新版 `smoke test` 结果:
|
||
|
||
```json
|
||
{
|
||
"ok": true
|
||
}
|
||
```
|
||
|
||
这说明在当前测试服条件下:
|
||
|
||
- API 主服务逻辑可用
|
||
- PostgreSQL 连接可用
|
||
- Redis 连接可用
|
||
- 缺表问题已解除
|
||
|
||
### 4. 临时验证态诊断包已导出
|
||
|
||
本次测试服诊断产物:
|
||
|
||
- 目录:`/www/wwwroot/getDomain/diagnostics/diag_20260416_133701`
|
||
- 压缩包:`/www/wwwroot/getDomain/diagnostics/diag_20260416_133701.tar.gz`
|
||
|
||
可用于后续继续排障或归档。
|
||
|
||
## 四、正式服务态已补验证通过
|
||
|
||
在后续继续收口过程中,已经额外完成了正式 `systemd` 服务态验证,结果如下:
|
||
|
||
### 1. 正式服务已落地
|
||
|
||
已安装并启用:
|
||
|
||
- `domaincheck-api`
|
||
- `domaincheck-worker`
|
||
|
||
并已确认两者为 `active (running)`。
|
||
|
||
### 2. 运行模式已切换成功
|
||
|
||
正式服务态下接口返回已确认:
|
||
|
||
- `/health` 中 `worker_mode = linux-systemd`
|
||
- `/api/v1/runtime/preflight` 中 `worker_mode = linux-systemd`
|
||
- `/api/v1/runtime/status` 中:
|
||
- `api.service_name = domaincheck-api`
|
||
- `worker.service_name = domaincheck-worker`
|
||
- `worker.running = true`
|
||
- `process_count = 1`
|
||
|
||
### 3. 正式服务态 smoke test 已通过
|
||
|
||
正式服务态下再次执行:
|
||
|
||
```bash
|
||
python smoke_test.py --base-url http://127.0.0.1:8100
|
||
```
|
||
|
||
结果仍为:
|
||
|
||
```json
|
||
{
|
||
"ok": true
|
||
}
|
||
```
|
||
|
||
### 4. 正式服务态诊断包已导出
|
||
|
||
正式服务态诊断产物:
|
||
|
||
- 目录:`/opt/domaincheck/diagnostics/diag_20260416_134923`
|
||
- 压缩包:`/opt/domaincheck/diagnostics/diag_20260416_134923.tar.gz`
|
||
|
||
### 5. 正式服务态中已确认的兼容与权限问题
|
||
|
||
本轮继续联调还确认并处理了两类真实 Linux 问题:
|
||
|
||
- `detect/jucha.py`、`detect/juming.py` 中存在 Windows 专属 `subprocess.STARTUPINFO()` 写法,已改为跨平台兼容处理
|
||
- 若曾以 `root` 手工运行过 API/Worker,可能会留下 `root` 所有者的运行文件,导致正式 `systemd` 服务用户无法写入
|
||
|
||
其中已实际踩到并修复的权限点包括:
|
||
|
||
- `domain-api/runtime/` 目录权限
|
||
- `domainCheck/detect_worker.log` 文件权限
|
||
|
||
这个问题的表现是:
|
||
|
||
- `/api/v1/imports/upload` 因无法创建 `runtime/imports/` 返回 `500`
|
||
- Worker 因无法写 `detect_worker.log` 进入循环重启
|
||
|
||
### 6. 运行中心控制链路已补通
|
||
|
||
本轮继续验证后,运行中心里的 Linux 控制动作也已经打通:
|
||
|
||
- Worker `start` / `stop` 已可通过 `sudo -n systemctl` 正常执行
|
||
- API 自重启已改为 `systemctl --no-block restart domaincheck-api`
|
||
|
||
这样处理后,`systemd` 会异步接管重启流程,接口可以先返回成功,避免出现“服务其实已经重启成功,但调用方因为等待自身停机而收到 `500`”的误导性现象。
|
||
|
||
### 7. 服务态日志噪音已进一步收敛
|
||
|
||
本轮还额外处理了两类不会阻断功能、但会影响正式服务观察体验的日志噪音:
|
||
|
||
- Redis 配置订阅从阻塞 `listen()` 改为短轮询 `get_message()`,Linux 空闲时不再每分钟刷 `Redis订阅失败: Timeout reading from socket`
|
||
- `offscreen` 模式下去掉 Qt 不支持的按钮样式属性,Worker 启动时不再刷 `Unknown property transition/transform/box-shadow`
|
||
- Worker 图标资源定位改为优先使用 `detect_worker.py` 同目录,Linux 服务态不再误报 `/opt/new_logo.svg`、`/opt/favicon2.ico` 不存在
|
||
- 付费检测器改为按需初始化,默认关闭 `detect_jucha` / `detect_juziseo` 时,不再在启动阶段报 cookie 文件缺失
|
||
- Redis 未加载 Bloom 模块时保留为降级说明,继续使用普通缓存,不再作为故障级告警处理
|
||
|
||
这几项修改的结果是:
|
||
|
||
- `domaincheck-worker` 仍保持 `active (running)`
|
||
- `/api/v1/runtime/status` 中 `worker.running = true`
|
||
- 正式测试服日志更适合持续观察和上线前留档
|
||
|
||
## 五、这次联调后已经明确固化的部署规则
|
||
|
||
后续无论谁再部署到 Linux,新环境都必须遵守下面这条:
|
||
|
||
> 如果 PostgreSQL 使用的是新库,必须先执行 `domainCheck/init_database.py` 初始化数据库结构。
|
||
|
||
否则至少这些接口会直接失败:
|
||
|
||
- `/api/v1/dashboard/overview`
|
||
- `/api/v1/detect/status`
|
||
- `/api/v1/imports/summary`
|
||
|
||
这个规则已经同步补入:
|
||
|
||
- [05_domainCheck_Linux部署清单.md](./05_domainCheck_Linux部署清单.md)
|
||
- [domain-api/deploy/linux/README.md](../domain-api/deploy/linux/README.md)
|
||
|
||
## 六、当前已完成项清单
|
||
|
||
以下内容可以视为“已经完成”:
|
||
|
||
### 1. 代码与仓库层
|
||
|
||
- `domainCheck` 已并入外层总仓库,不再是子模块指针
|
||
- 根目录总 `README.md` 已补齐
|
||
- `.gitignore` 已补强
|
||
- 本地敏感文件、cookies、本地 Node runtime 已从 git 中移除
|
||
|
||
### 2. Web/API 层
|
||
|
||
- `domain-web` 主要页面已完成
|
||
- `domain-api` 主要接口已完成
|
||
- 运行中心、系统设置、导入、导出、日志诊断、自检、自测均已具备
|
||
- 正式 `systemd` 服务态下 `/health`、`/runtime/preflight`、`/runtime/status`、`smoke test` 已全部通过
|
||
|
||
### 3. 交付层
|
||
|
||
- 交付包已生成
|
||
- SHA256 校验已生成
|
||
- 验包脚本可用
|
||
- 发布准备报告可用
|
||
- 最新交付指针可用
|
||
|
||
### 4. Linux 文档层
|
||
|
||
- Linux 部署清单已完成
|
||
- Linux 诊断采集脚本已完成
|
||
- Linux 联调输入清单已完成
|
||
- 导航索引文档已完成
|
||
|
||
### 5. 真实业务回归层
|
||
|
||
- 已通过 API 上传样本 TXT
|
||
- 已确认导入结果:
|
||
- 总数 `5`
|
||
- 有效 `3`
|
||
- 新增 `3`
|
||
- 无效 `2`
|
||
- 已确认 `domains_total = 3`
|
||
- 已确认 `detect_tasks_total = 3`
|
||
- 已确认导入后会自动创建 `detect_tasks`
|
||
|
||
## 七、当前未完成项清单
|
||
|
||
以下内容仍属于“后续要做”:
|
||
|
||
### 1. Worker 真实联动验证
|
||
|
||
还应继续确认:
|
||
|
||
- Worker 在线状态
|
||
- Worker 进程数
|
||
- 检测控制页读取是否正常
|
||
- `detect_worker.log` 是否正常写入
|
||
|
||
### 2. 导入更多真实数据后的业务复测
|
||
|
||
当前已经完成一轮小样本回归,不再是空库空表态。
|
||
|
||
后续应至少补一次真实业务复测:
|
||
|
||
- 导入更接近真实业务规模的域名样本
|
||
- 查看 `domains` 持续增长
|
||
- 查看 `detect_tasks` 持续生成
|
||
- 再验证筛选与导出
|
||
|
||
### 3. 长时间运行与代理池观察
|
||
|
||
仍建议继续验证:
|
||
|
||
- Worker 长时运行稳定性
|
||
- Redis 订阅超时后的重连是否持续稳定
|
||
- 国内网络环境下代理池真实可用率
|
||
- Wayback 首次全量快照列表的耗时表现
|
||
|
||
## 八、后续继续收口的推荐顺序
|
||
|
||
建议 Linux 上的下一位接手人严格按下面顺序执行。
|
||
|
||
### 第一步:确认目录完整
|
||
|
||
确认至少存在:
|
||
|
||
- `/opt/domaincheck/domainCheck`
|
||
- `/opt/domaincheck/domain-api`
|
||
- `/opt/domaincheck/domain-web`
|
||
|
||
### 第二步:确认数据库结构
|
||
|
||
如果是新库,先执行:
|
||
|
||
```bash
|
||
cd /opt/domaincheck/domainCheck
|
||
python3 init_database.py
|
||
```
|
||
|
||
然后确认:
|
||
|
||
```sql
|
||
select tablename
|
||
from pg_tables
|
||
where schemaname = 'public'
|
||
order by tablename;
|
||
```
|
||
|
||
### 第三步:落 systemd
|
||
|
||
使用这些模板:
|
||
|
||
- `domain-api/deploy/systemd/domain-api.service`
|
||
- `domain-api/deploy/systemd/domain-worker.service`
|
||
|
||
如果此前用 `root` 手工跑过 API 或 Worker,建议先确认下面这些路径对正式服务用户可写:
|
||
|
||
- `domain-api/runtime/`
|
||
- `domainCheck/detect_worker.log`
|
||
|
||
### 第四步:启动正式服务
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable domaincheck-api
|
||
sudo systemctl enable domaincheck-worker
|
||
sudo systemctl start domaincheck-api
|
||
sudo systemctl start domaincheck-worker
|
||
```
|
||
|
||
### 第五步:检查服务状态
|
||
|
||
```bash
|
||
systemctl status domaincheck-api --no-pager -l
|
||
systemctl status domaincheck-worker --no-pager -l
|
||
journalctl -u domaincheck-api -n 200 --no-pager
|
||
journalctl -u domaincheck-worker -n 200 --no-pager
|
||
```
|
||
|
||
### 第六步:检查 API 状态
|
||
|
||
```bash
|
||
curl http://127.0.0.1:8100/health
|
||
curl http://127.0.0.1:8100/api/v1/runtime/preflight
|
||
curl http://127.0.0.1:8100/api/v1/runtime/status
|
||
```
|
||
|
||
### 第七步:做一轮导入回归
|
||
|
||
至少验证:
|
||
|
||
- `/api/v1/imports/upload`
|
||
- `/api/v1/imports/tasks`
|
||
- `/api/v1/imports/summary`
|
||
- `domains` 增长
|
||
- `detect_tasks` 自动创建
|
||
|
||
目标是确认:
|
||
|
||
- `status = ok`
|
||
- `worker_mode = linux-systemd`
|
||
|
||
### 第七步:运行 smoke test
|
||
|
||
```bash
|
||
cd /opt/domaincheck/domain-api/deploy/linux
|
||
python3 smoke_test.py --base-url http://127.0.0.1:8100
|
||
```
|
||
|
||
### 第八步:如异常则导出诊断包
|
||
|
||
```bash
|
||
cd /opt/domaincheck/domain-api/deploy/linux
|
||
bash collect_diagnostics.sh /opt/domaincheck
|
||
```
|
||
|
||
## 九、后续交接给 Linux 上 Codex 时,最该提供的材料
|
||
|
||
如果后续换一位 Linux 上的 Codex 接手,优先给他这些:
|
||
|
||
### 1. 当前关键结论
|
||
|
||
- 当前最大已修复问题:数据库未初始化
|
||
- 当前最大未收口问题:正式 `systemd` 服务态还没完全落定
|
||
|
||
### 2. 当前最关键文件
|
||
|
||
- `domainCheck/.env`
|
||
- `api_health_curl.txt`
|
||
- `api_preflight_curl.txt`
|
||
- `api_runtime_curl.txt`
|
||
- 诊断包:
|
||
- `diag_20260416_133701.tar.gz`
|
||
|
||
### 3. 必看文档
|
||
|
||
- [12_domainCheck_导航索引.md](./12_domainCheck_导航索引.md)
|
||
- [11_domainCheck_Linux联调输入清单.md](./11_domainCheck_Linux联调输入清单.md)
|
||
- [05_domainCheck_Linux部署清单.md](./05_domainCheck_Linux部署清单.md)
|
||
- [08_domainCheck_交付说明.md](./08_domainCheck_交付说明.md)
|
||
|
||
## 十、最终交接结论
|
||
|
||
当前项目不再是“开发未完成”,而是:
|
||
|
||
> 开发已完成,Linux 测试服联调已完成第一轮关键打通,剩余工作集中在正式服务化部署与上线前最后复测。
|
||
|
||
因此,对下一位接手者的要求不是“继续开发功能”,而是:
|
||
|
||
- 完成正式 Linux 服务落地
|
||
- 跑正式服务态 smoke test
|
||
- 如有异常,基于诊断包继续排障
|
||
- 最终完成上线前收口
|