mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
172 lines
6.8 KiB
Markdown
172 lines
6.8 KiB
Markdown
# 日常维护与故障排查
|
|
|
|
本文档记录正式看板的运行基线、常用诊断方法和已确认故障。接口路径、监听端口、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 需要临时预览时可以单独启动,用完后应及时停止。
|
|
|
|
## 快速排查
|
|
|
|
### 登录与会话
|
|
|
|
- 登录页返回 503:检查 systemd 是否配置 `WEREAD_SESSION_SECRET`,并确认数据库迁移已创建 `weread_auth` 表。
|
|
- 首次设置提示初始化口令无效:确认 `WEREAD_AUTH_SETUP_TOKEN` 已在服务环境中配置;账号创建成功后应从服务配置移除该值。
|
|
- 输入正确密码后仍回到登录页:公网必须通过 HTTPS 访问,检查 Cookie 的 `Secure` 标记与 `WEREAD_SESSION_COOKIE_SECURE` 设置;本机 HTTP 预览才设为 `0`。
|
|
- 页面可打开但 API 返回 401:登录 Cookie 未随请求发送,先重新登录并确认页面与 API 使用同一主机名和协议。
|
|
- 登录后写操作返回 CSRF 错误:刷新页面获取新的 token 后重试,不要跨域代理前端与 API。
|
|
|
|
页面出现“请求失败”时,按下面的顺序检查。
|
|
|
|
### 检查监听端口
|
|
|
|
本机:
|
|
|
|
```sh
|
|
lsof -nP -iTCP -sTCP:LISTEN
|
|
```
|
|
|
|
服务器:
|
|
|
|
```sh
|
|
sudo ss -ltnp
|
|
sudo systemctl status weread.service --no-pager
|
|
```
|
|
|
|
确认正式服务只监听预期端口,并核对进程的启动时间与 Python 路径:
|
|
|
|
```sh
|
|
ps -fp <PID>
|
|
lsof -a -p <PID> -d cwd
|
|
```
|
|
|
|
### 分层检查接口
|
|
|
|
本机设置了 HTTP 代理时,必须绕过代理访问本地地址:
|
|
|
|
```sh
|
|
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 证书和接口超时,不要只修改前端路径。
|
|
|
|
服务器日志:
|
|
|
|
```sh
|
|
sudo journalctl -u weread.service -n 100 --no-pager
|
|
```
|
|
|
|
### 检查部署分支
|
|
|
|
自动部署只允许 `master`。先检查 GitHub Webhook 的 Recent Deliveries、服务器 `weread-webhook.service` 日志和 Nginx HTTPS 转发;仅推送 `dev` 不会部署。服务器部署日志中的拉取目标必须是 `origin/master`,出现其他分支时应停止发布并检查 Webhook 环境变量与 `deploy.sh`。
|
|
|
|
Webhook 排查命令:
|
|
|
|
```bash
|
|
sudo systemctl status weread-webhook.service --no-pager
|
|
sudo journalctl -u weread-webhook.service -n 100 --no-pager
|
|
sudo nginx -t
|
|
curl -fsS https://laohang.space/github/webhook-health
|
|
```
|
|
|
|
GitHub 显示签名错误时,确认 Webhook Secret 与 `/etc/weread-webhook.env` 完全一致;显示 202 但没有部署时,确认仓库全名、`refs/heads/master` 和部署锁状态。不要通过请求体传入 Shell 命令。
|
|
|
|
## 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`。
|
|
|
|
完整因果链路如下:
|
|
|
|
```text
|
|
接口调整需要重启服务
|
|
-> 启动脚本选择了不同的 Python
|
|
-> 新 Python 无法找到 CA 证书
|
|
-> 微信读书 HTTPS 请求失败
|
|
-> 聚合接口返回 502
|
|
-> 前端显示“请求失败”
|
|
```
|
|
|
|
因此,接口调整是触发条件,不是 HTTPS 故障本身。兼容路径只能处理旧进程返回 404 的过渡状态;同一后端因上游 TLS 失败而返回 502 时,切换 `/api/reading/*` 或 `/api/v2/*` 都不能解决问题。
|
|
|
|
### 诊断证据
|
|
|
|
检查 Python 与默认 CA 文件:
|
|
|
|
```sh
|
|
python3 -c "import sys, ssl; print(sys.executable); print(ssl.get_default_verify_paths())"
|
|
```
|
|
|
|
故障环境中,`cafile` 为 `None`,且 Python 预期的证书文件不存在。系统证书 `/etc/ssl/cert.pem` 可用,使用它重新启动后,状态、书架和概览接口均恢复为 200。
|
|
|
|
### 恢复方式
|
|
|
|
本机临时恢复:
|
|
|
|
```sh
|
|
SSL_CERT_FILE=/etc/ssl/cert.pem PORT=8080 python3 app.py
|
|
```
|
|
|
|
服务器由 systemd 管理时,先确认服务器证书文件的实际路径;仅在 Python 默认 CA 路径缺失时,为 `weread.service` 配置 `SSL_CERT_FILE`,然后执行:
|
|
|
|
```sh
|
|
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` 静态预览均已停止。
|
|
|
|
## 故障记录模板
|
|
|
|
新增故障时使用以下结构:
|
|
|
|
```markdown
|
|
## YYYY-MM-DD:故障标题
|
|
|
|
### 现象
|
|
|
|
### 根因
|
|
|
|
### 诊断证据
|
|
|
|
### 恢复方式
|
|
|
|
### 预防与验收
|
|
```
|