Files
huike-back/CLAUDE.md
T
2026-05-01 21:10:09 +08:00

6.5 KiB
Raw Blame History

huike-back 项目指南

服务器标识

环境 服务器 SSH 用户 说明
正式服 (production) alchemy-studio.cn (152.136.103.69, CentOS 8) alchemysudo -u alchemysudo su - alchemy 线上生产环境
测试服 (test) moicen.com (101.43.244.164, Ubuntu 24.04) weli 测试验证环境

正式服 = alchemy,测试服 = moicen,不要搞混。

正式服 (alchemy) 部署要点

  • 所有服务以 alchemy 用户运行(sudo -u alchemy -H bash
  • 代码路径:/mnt/huiwing/huike-back/(新版本拆分仓库,非旧 monorepo)
  • AuthCore 路径:/mnt/huiwing/AuthCore/
  • 旧 monorepo (/mnt/huiwing/huiwing/) 已由拆分仓库替代,Java 服务已全部下线

测试服 (moicen) 部署要点

  • 代码路径:/home/weli/works/huike-back/
  • AuthCore 路径:/home/weli/works/AuthCore/

E2E 测试流程(新功能开发标准流程)

为节约 CI 资源、加快迭代速度,新功能开发采用 先本地验证,再推送 CI 的流程:

  1. 本地开发 & 编译cargo check 确保无编译错误
  2. 部署测试服 (moicen)git push → SSH 登录 moicen → git pullcargo build --release
  3. 本地发起 e2e 测试 — 在本地运行 e2e 测试套件,请求指向 moicen 测试服
  4. 验证通过后推送 CIgit push origin master → GitHub Actions 自动运行 cargo check + 全量 e2e
  5. 部署正式服 (alchemy) — SSH 登录 alchemy → git pullcargo build --release → 重启服务
  6. 正式服 CI smoke test — 部署后立即触发 GitHub Actions 的 prod smoke test workflow,验证正式服 API 响应正常。若 smoke test 失败,立即回滚并排查

Why: 大部分问题在步骤 2-3 就能发现,避免反复触发 CI 浪费排队时间和 GitHub Actions 配额。

部署原则

禁止使用 scp/rsync 部署代码。 所有部署必须走 GitHub push → 服务器 git pull 的流程。

# 本地
git push

# 服务器
ssh <server>
cd /path/to/repo
git pull --ff-only
cargo build --release  # 后端
# 或 sh cp_dist_moicen.sh / cp_dist_huiwing.sh  # 前端

如果服务器缺少对应仓库,先在服务器上用 git clone 克隆,而不是从本机传文件。

Why: 二进制/构建产物拷贝绕过构建系统,会引入静默的架构或链接不匹配问题。git 工作流确保二进制与代码一致、依赖已解析、构建可重复。

前端部署提醒:必须上传静态资源到又拍云 CDN

cp_dist_huiwing.sh / cp_dist_moicen.sh 已自动包含又拍云上传步骤。

严禁只手动 sudo cp 而不上传 CDN。HTML 中的 JS/CSS 链接指向 static.* CDN 域名(又拍云),而非 nginx 本地目录。若只拷贝到 nginx,JS 会返回 404,页面为空白白屏。

# 正确:执行完整部署脚本
sh cp_dist_huiwing.sh

# 错误(从仓库复制到 nginx 但跳过 CDN,会导致白屏)
sudo cp -r dist/* /usr/local/openresty/nginx/html/music-room/

手动修复白屏:

cd /mnt/huiwing/huike-front/cdn
sh upload_assets.sh .huiwing_upyun_pass 1

htyproc (Task Processor)

启动流程

cd /path/to/huike-back/htyproc
bash start.sh

启动后 proc server 默认处于 PENDING 状态,不会处理任务。需要调用 API 切换为 RUNNING

# proc server 默认 PENDING,必须手动 start
curl -s 'http://127.0.0.1:3004/api/v1/proc/start'

# 检查状态
curl -s 'http://127.0.0.1:3004/api/v1/proc/status'
# → {"r":true,"d":"RUNNING",...}

# 停止
curl -s 'http://127.0.0.1:3004/api/v1/proc/stop'

注意/api/v1/proc/start 是 GET 方法(不是 POST),路由定义在 htyproc/src/proc_api.rs

重启后必须手动调用 start 才能恢复任务处理。

重置 FAILED 任务为 PENDING

若任务因临时故障(如 AI API 不可用)标记为 FAILED,可手动重置重新处理:

ssh moicen
sudo -u postgres psql -d htytask_moicen -c "UPDATE dbtack SET task_status='PENDING', updated_at=NOW(), updated_by='manual_reset' WHERE task_id='<task_id>';"

确保 proc 为 RUNNING 状态后,等待 WAIT_SEC(默认 5s)即可自动拾取。

NGX_URL 配置陷阱

.envNGX_URL 不要包含 /api/ngx 后缀 — 代码 clients.rs:98 会拼接 /api/ngx/audio/convert,两者叠加会变成双 /api/ngx/api/ngx/ 路径,导致 OpenResty 返回 405。

# 错误
NGX_URL=https://admin.huiwings.cn/api/ngx

# 正确
NGX_URL=https://admin.huiwings.cn

日志

日志文件:htyproc/htyproc.nohup.log,受 logrotate 管理。


AI API 网络架构

架构说明

AI APIFlask,端口 5000)部署在独立的 AI 服务器上(Mac mini 192.168.0.115),Flask 运行在 Podman 容器 内,通过 NPS + SSH 隧道穿透访问:

AI Server Podman container(port 5000)
  → Podman gvproxy(port 5000)
  → Mac host(port 5000)
  → NPS client → NPS server alchemy:10001
  → alchemy(port 5000 via SSH -L) 
  → moicen(port 5000 via SSH -L)
  • 穿透链路:本机 → ssh weli@alchemy-studio.cnssh -p 10001 weli@localhost(经 NPS 隧道)→ Mac → /usr/local/bin/podman exec ai-api
  • 容器信息localhost/ai-api:latest,端口映射 5000→5000/tcp5909→5901/tcp2222→22/tcp
  • 便捷工具plan_skills/tools/huiwing-ai-api(一键执行容器命令,无需逐层 SSH
  • 详细文档:见 plan_skills/moicen/moicen-access-ai-api-container.md

SSH 隧道命令

# alchemy 上的隧道(由 tmux ai-tunnel 守护,自动重连)
tmux new-session -d -s ai-tunnel 'while true; do sleep 3; ssh -L 5909:localhost:5909 -L 5000:localhost:5000 weli@localhost -p 10001; done'

# moicen 到 alchemy 转发
ssh -L 5000:localhost:5000 weli@alchemy-studio.cn

OpenResty 反向代理

两台服务器的 OpenResty 都配置了 ai.conf,将 https://ai.<domain>/api/v1/ai/* 代理到 http://127.0.0.1:5000/(注意尾部 / 会剥离 /api/v1/ai 前缀)。

Flask 路由实际路径(无前缀):

  • /form_image_compress_audit — 图片压缩审计
  • /compare — AI 评分对比

验证 AI API 可用性

curl -s 'https://ai.moicen.com/api/v1/ai/form_image_compress_audit' \
  -X POST -H 'Content-Type: application/json' \
  -H 'HtySudoerToken: test' -H 'HtyHost: ts.moicen.com' \
  -d '{"url":"https://test.com/test.jpg"}'
# → {"d":{"acknowledged":true},"e":null,"r":true}