Files
WeReadBoard/docs/troubleshooting.md
T

5.6 KiB

日常维护与故障排查

本文档记录正式看板的运行基线、常用诊断方法和已确认故障。接口路径、监听端口、Python 环境、启动脚本、systemd 服务或部署流程发生变化时,必须同步更新本文档;出现新的线上或本地故障时,按日期追加记录,不覆盖历史结论。

运行基线

项目 当前约定
本地正式看板端口 8080
当前 API 前缀 /api/reading/*
兼容 API 前缀 /api/v2/*,仅用于旧客户端过渡
项目 Python 优先使用项目根目录 .venv/bin/python
自动部署分支 仅 master;推送或手动触发均不部署其他分支
服务器服务 weread.service,端口以服务中的 PORT 为准
服务器目录 /opt/weread-board/WeReadBoard

同一运行环境只保留一个正式服务实例。不要同时使用 start_server.sh 和 start_dashboard.sh 启动不同端口,否则静态文件、后端路由和 Python 环境可能来自不同进程,容易产生误判。历史静态 Demo 需要临时预览时可以单独启动,用完后应及时停止。

快速排查

页面出现“请求失败”时,按下面的顺序检查。

检查监听端口

本机:

lsof -nP -iTCP -sTCP:LISTEN

服务器:

sudo ss -ltnp
sudo systemctl status weread.service --no-pager

确认正式服务只监听预期端口,并核对进程的启动时间与 Python 路径:

ps -fp <PID>
lsof -a -p <PID> -d cwd

分层检查接口

本机设置了 HTTP 代理时,必须绕过代理访问本地地址:

curl --noproxy '*' -i http://127.0.0.1:8080/
curl --noproxy '*' -i http://127.0.0.1:8080/api/reading/status
curl --noproxy '*' -i 'http://127.0.0.1:8080/api/reading/shelf?tab=all&progress=0'
curl --noproxy '*' -i 'http://127.0.0.1:8080/api/reading/dashboard?period=week'
  • 页面返回 200、API 返回 404:运行中的后端没有加载当前路由,检查部署提交与服务重启。
  • API 返回 502:路由已经加载,但数据库或微信读书上游调用失败,查看响应正文和服务日志。
  • 请求一直等待:检查上游网络、DNS、TLS 证书和接口超时,不要只修改前端路径。

服务器日志:

sudo journalctl -u weread.service -n 100 --no-pager

检查部署分支

自动部署只允许 master。如果 Actions 没有启动,先确认提交是否已经合并并推送到 master;仅推送 dev 不会部署。服务器部署日志中的拉取目标也必须是 origin/master,出现其他分支时应停止发布并检查工作流与 deploy.sh。

2026-09-14:接口调整后页面请求失败

现象

  • http://127.0.0.1:8080/ 可以打开,但页面显示“请求失败”。
  • /api/reading/shelf 和 /api/reading/dashboard 返回 502。
  • 旧的 8770 进程仍能通过 /api/v2/status 返回数据。

根因

接口调整只修改了 Flask 路由名称和前端请求前缀,微信读书 HTTPS 请求逻辑没有变化。真正差异来自服务重启后选择了另一套 Python:

  • 旧 8770 进程使用 WorkBuddy Python,其默认 CA 文件为 /private/etc/ssl/cert.pem。
  • 新 8080 进程因项目没有 .venv,由 start_server.sh 选择系统 Python。
  • 该系统 Python 的默认 CA 文件为空,访问 https://i.weread.qq.com 时出现 CERTIFICATE_VERIFY_FAILED。

完整因果链路如下:

接口调整需要重启服务
-> 启动脚本选择了不同的 Python
-> 新 Python 无法找到 CA 证书
-> 微信读书 HTTPS 请求失败
-> 聚合接口返回 502
-> 前端显示“请求失败”

因此,接口调整是触发条件,不是 HTTPS 故障本身。兼容路径只能处理旧进程返回 404 的过渡状态;同一后端因上游 TLS 失败而返回 502 时,切换 /api/reading/* 或 /api/v2/* 都不能解决问题。

诊断证据

检查 Python 与默认 CA 文件:

python3 -c "import sys, ssl; print(sys.executable); print(ssl.get_default_verify_paths())"

故障环境中,cafile 为 None,且 Python 预期的证书文件不存在。系统证书 /etc/ssl/cert.pem 可用,使用它重新启动后,状态、书架和概览接口均恢复为 200。

恢复方式

本机临时恢复:

SSL_CERT_FILE=/etc/ssl/cert.pem PORT=8080 python3 app.py

服务器由 systemd 管理时,先确认服务器证书文件的实际路径;仅在 Python 默认 CA 路径缺失时,为 weread.service 配置 SSL_CERT_FILE,然后执行:

sudo systemctl daemon-reload
sudo systemctl restart weread.service

不要关闭 TLS 校验,也不要在代码中使用不验证证书的 SSL Context。

预防与验收

  1. 部署和本地启动统一使用项目 .venv/bin/python,不要让不同启动脚本静默选择不同解释器。
  2. 重启前检查 Python 的 ssl.get_default_verify_paths(),确认 CA 文件存在且可读。
  3. 每次只保留一个正式服务端口,停止旧实例后再验收新实例。
  4. 接口、端口、Python 环境、启动脚本、systemd 配置或部署方式变化时,同步更新本文档的“运行基线”和相关故障记录。
  5. 验收必须同时检查页面、status、shelf 和 dashboard,不能只确认首页返回 200。

本次本地恢复后的验收结果:正式服务仅监听 8080,页面及上述三个 API 均返回 200;旧 8770 实例和 8766 静态预览均已停止。

故障记录模板

新增故障时使用以下结构:

## YYYY-MM-DD:故障标题

### 现象

### 根因

### 诊断证据

### 恢复方式

### 预防与验收