容错处理
This commit is contained in:
1 parent
f44e2ccf52
commit
f358cfb7c7
8 files changed
+988
-21
No files matched your search
@@ -1,3 +1,86 @@
|
||||
/**
|
||||
* AI 写作入口页(左右双栏:聊天面板 + 草稿预览)。
|
||||
*
|
||||
* ──────────────────────────────────────────────────────────────────────────
|
||||
* Docker 内网部署后「会话丢失 / transcript 报 500 / resume 报 400」排查指南
|
||||
* ──────────────────────────────────────────────────────────────────────────
|
||||
*
|
||||
* 后端涉及接口(前缀 /api/ai-writing):
|
||||
* POST /start 启动写作流程
|
||||
* GET /{session_id}/stream SSE 进度流
|
||||
* POST /{session_id}/resume 提交用户干预 → 继续流程
|
||||
* PUT /sessions/{session_id}/transcript 保存对话时间线
|
||||
*
|
||||
* ── 1) 确认 alembic 迁移已跑过(修 transcript 500)─────────────────────
|
||||
* transcript 列在 MySQL 上原是 TEXT(64 KB 上限),长时间线会溢出抛 500。
|
||||
* 迁移 20260519_02 把它改成 LONGTEXT。容器启动会自动跑,验证方法:
|
||||
*
|
||||
* docker exec <gateway> sh -c "cd /app/backend \
|
||||
* && PYTHONPATH=. uv run alembic current"
|
||||
* docker exec <mysql> mysql -uroot -p<pwd> deerflow -e \
|
||||
* "SHOW COLUMNS FROM ai_writing_sessions LIKE 'transcript';"
|
||||
*
|
||||
* 列类型应是 longtext。若仍是 text,手动执行:
|
||||
* docker exec <gateway> sh -c "cd /app/backend \
|
||||
* && PYTHONPATH=. uv run alembic upgrade head"
|
||||
*
|
||||
* ── 2) 确认 .deer-flow 数据卷已挂出(修「容器没重启也丢会话」)──────
|
||||
* AI 写作 graph 的 checkpointer 已从 MemorySaver 换成 AsyncSqliteSaver,
|
||||
* 文件落到 .deer-flow/data/checkpoints.db。docker-compose 必须把该目录
|
||||
* 挂出来,否则容器重启数据照样丢:
|
||||
*
|
||||
* services:
|
||||
* gateway:
|
||||
* volumes:
|
||||
* - ./data:/app/.deer-flow # 关键:挂出 .deer-flow
|
||||
*
|
||||
* ── 3) 确认 worker 数 = 1(关键嫌疑:多 worker 内存隔离)────────────
|
||||
* _event_queues / _session_pending_pause 都是模块级 dict,每个 worker
|
||||
* 一份。多 worker 下,/start 命中 worker A、/resume 命中 worker B,B
|
||||
* 的 dict 没有这个 session → 404/「会话丢失」。
|
||||
*
|
||||
* docker exec <gateway> ps -ef | grep -E 'uvicorn|gunicorn'
|
||||
*
|
||||
* 若 > 1:要么把启动参数改成 --workers 1,要么在 nginx 加 sticky
|
||||
* session(ip_hash / cookie),要么把队列搬 Redis。
|
||||
*
|
||||
* ── 4) 排查节点异常(嫌疑:graph 节点抛错触发清理分支)─────────────
|
||||
* _stream_graph_segment 的 except 分支会清掉 _event_queues[session_id],
|
||||
* 用户下一次 resume 就 404。日志里搜:
|
||||
*
|
||||
* docker logs <gateway> 2>&1 | grep -E \
|
||||
* 'ai_writing graph segment failed|ai_writing.*error' | tail -50
|
||||
*
|
||||
* ── 5) 排查反向代理掐 SSE 长连接(嫌疑:proxy_read_timeout 太短)───
|
||||
* SSE 默认连接挂半个小时以上,nginx 默认 60s 会断。检查内网反代:
|
||||
*
|
||||
* grep -rE 'proxy_read_timeout|sse|keepalive' /etc/nginx/
|
||||
*
|
||||
* 需在 SSE 路由上加:proxy_read_timeout 3600s; proxy_buffering off;
|
||||
*
|
||||
* ── 定期清理(每天 03:00 跑)────────────────────────────────────────
|
||||
* config.yaml -> ai_writing.cleanup 段(retention_days: 7)。联动清理
|
||||
* MySQL 业务表 + SQLite checkpointer 里的 thread 状态。手动验证:
|
||||
*
|
||||
* docker exec <mysql> mysql -uroot -p<pwd> deerflow -e \
|
||||
* "SELECT COUNT(*) FROM ai_writing_sessions \
|
||||
* WHERE updated_at < NOW() - INTERVAL 7 DAY;"
|
||||
*
|
||||
* ── 不想等凌晨 3 点?手动触发一次清理(admin only)──────────────────
|
||||
* POST /api/ai-writing/admin/cleanup
|
||||
* Body(全部可选,留空走 config 默认):
|
||||
* { "retention_days": 7, "only_finished": false, "batch_size": 500 }
|
||||
* 返回:
|
||||
* { "deleted_db": N, "deleted_checkpoints": N,
|
||||
* "elapsed_seconds": X, "params": {...} }
|
||||
*
|
||||
* 例:清掉所有 1 小时前的会话(测试用):
|
||||
* curl -X POST http://<gateway>/api/ai-writing/admin/cleanup \
|
||||
* -H 'Content-Type: application/json' \
|
||||
* -H 'Cookie: <admin session cookie>' \
|
||||
* -d '{"retention_days": 0}'
|
||||
* ──────────────────────────────────────────────────────────────────────────
|
||||
*/
|
||||
import { useRef } from 'react';
|
||||
import { TooltipProvider } from '@/components/ui/tooltip';
|
||||
import type { GroupImperativeHandle } from 'react-resizable-panels';
|
||||
|
||||
Reference in new issue
Block a user