添加prefect调度
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
# Docker + Prefect 使用说明
|
||||
|
||||
当前方案是:
|
||||
|
||||
- 使用 [prefect.yaml](/Users/idss/YXT_Project/logistics-service/prefect.yaml) 管理 deployment
|
||||
- 使用 Docker 容器运行 Prefect worker
|
||||
- 由 Prefect Server 统一调度
|
||||
|
||||
当前只有一条调度:
|
||||
|
||||
- `12:00` 执行物流未发货数据同步,并写入飞书多维表格
|
||||
|
||||
## 1. 创建 Docker 镜像
|
||||
|
||||
在项目目录执行:
|
||||
|
||||
```bash
|
||||
cd /Users/idss/YXT_Project/logistics-service
|
||||
docker build -t logistics-service-prefect:0.1.0 .
|
||||
```
|
||||
|
||||
镜像构建特点:
|
||||
|
||||
- 基础镜像:`python:3.12-slim-bookworm`
|
||||
- 使用 `uv` 安装依赖
|
||||
- 使用清华 `apt` 和 `PyPI` 源
|
||||
- 依赖来源:[pyproject.toml](/Users/idss/YXT_Project/logistics-service/pyproject.toml)
|
||||
|
||||
## 2. 启动 Docker 容器
|
||||
|
||||
推荐使用 Compose。
|
||||
|
||||
项目里的 [docker-compose.yaml](/Users/idss/YXT_Project/logistics-service/docker-compose.yaml) 已经配置了:
|
||||
|
||||
- `.env`
|
||||
- `PREFECT_API_URL`
|
||||
- `FEISHU_CHAT_ID`
|
||||
- `host.docker.internal`
|
||||
- `uv_cache` 持久化卷
|
||||
- CPU / 内存资源限制
|
||||
|
||||
启动:
|
||||
|
||||
```bash
|
||||
cd /Users/idss/YXT_Project/logistics-service
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
停止:
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
查看运行状态:
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
```
|
||||
|
||||
当前容器名是:
|
||||
|
||||
```bash
|
||||
prefect-logistics-worker
|
||||
```
|
||||
|
||||
## 3. 容器启动后会做什么
|
||||
|
||||
容器启动后:
|
||||
|
||||
1. 加载 `.env`
|
||||
2. 创建 `/app/logs`
|
||||
3. 启动 `supervisord`
|
||||
4. 再由 [supervisord.conf](/Users/idss/YXT_Project/logistics-service/supervisord.conf) 启动:
|
||||
|
||||
```bash
|
||||
prefect worker start --pool "logistics-service-pool" --type process
|
||||
```
|
||||
|
||||
也就是说,这个容器的职责不是直接跑 flow,而是作为 Prefect worker 等待调度。
|
||||
|
||||
## 4. 注册 Prefect 调度
|
||||
|
||||
调度定义在 [prefect.yaml](/Users/idss/YXT_Project/logistics-service/prefect.yaml)。
|
||||
|
||||
当前 work pool 是:
|
||||
|
||||
```bash
|
||||
logistics-service-pool
|
||||
```
|
||||
|
||||
注册 deployment 的方式:
|
||||
|
||||
### 方式 A:在本机或服务器上直接执行
|
||||
|
||||
前提是当前环境里有 `prefect` CLI,并且能访问 `PREFECT_API_URL`:
|
||||
|
||||
```bash
|
||||
cd /Users/idss/YXT_Project/logistics-service
|
||||
prefect deploy --all
|
||||
```
|
||||
|
||||
### 方式 B:在容器里执行
|
||||
|
||||
如果宿主机没有 `prefect` 命令,可以直接在容器里执行:
|
||||
|
||||
```bash
|
||||
docker exec -it prefect-logistics-worker sh -lc 'cd /app && prefect deploy --all'
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- 这条命令要求容器里的 `PREFECT_API_URL` 可访问
|
||||
- 如果你看到 `ConnectError`,通常是 `.env` 里的 `PREFECT_API_URL` 地址在容器里不可达
|
||||
|
||||
## 5. 自动执行是怎么发生的
|
||||
|
||||
完整流程如下:
|
||||
|
||||
1. `prefect deploy --all` 把 [prefect.yaml](/Users/idss/YXT_Project/logistics-service/prefect.yaml) 注册到 Prefect Server
|
||||
2. Prefect Server 根据 cron 在每天 `12:00` 触发:
|
||||
- `logistics-bitable-sync-daily`
|
||||
3. `prefect-logistics-worker` 容器里的 worker 从 `logistics-service-pool` 拉取任务
|
||||
4. worker 执行 [prefect_logistics_scheduler.py](/Users/idss/YXT_Project/logistics-service/prefect_logistics_scheduler.py) 里的 flow
|
||||
5. flow 调用 [import_logistics_to_feishu_bitable.py](/Users/idss/YXT_Project/logistics-service/import_logistics_to_feishu_bitable.py):
|
||||
- 查询 PostgreSQL
|
||||
- 删除多维表旧记录
|
||||
- 写入新记录
|
||||
6. 同步完成或失败后,使用 `FEISHU_APP_ID`、`FEISHU_APP_SECRET` 和 `FEISHU_CHAT_ID` 推送结果到飞书群
|
||||
|
||||
## 6. 单次手动执行
|
||||
|
||||
手动跑一次同步:
|
||||
|
||||
```bash
|
||||
python /Users/idss/YXT_Project/logistics-service/prefect_logistics_scheduler.py --mode sync
|
||||
```
|
||||
|
||||
如果要在 Docker 里手动执行:
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
--env-file /Users/idss/YXT_Project/logistics-service/.env \
|
||||
-e PREFECT_API_URL=http://host.docker.internal:4200/api \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
logistics-service-prefect:0.1.0 \
|
||||
python prefect_logistics_scheduler.py --mode sync
|
||||
```
|
||||
|
||||
## 7. Docker 中的日志
|
||||
|
||||
现在日志分成三层:
|
||||
|
||||
### 7.1 容器标准输出日志
|
||||
|
||||
查看 worker 容器日志:
|
||||
|
||||
```bash
|
||||
docker logs -f prefect-logistics-worker
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```bash
|
||||
cd /Users/idss/YXT_Project/logistics-service
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
这里通常能看到:
|
||||
|
||||
- worker 启动日志
|
||||
- Prefect 调度执行日志
|
||||
- Python 进程报错堆栈
|
||||
|
||||
### 7.2 容器内本地文件日志
|
||||
|
||||
worker 的 supervisor 日志会写到:
|
||||
|
||||
- `/app/logs/prefect_worker.out.log`
|
||||
- `/app/logs/prefect_worker.err.log`
|
||||
|
||||
查看方式:
|
||||
|
||||
```bash
|
||||
docker exec -it prefect-logistics-worker sh
|
||||
tail -f /app/logs/prefect_worker.out.log
|
||||
```
|
||||
|
||||
### 7.3 Prefect UI 日志
|
||||
|
||||
在 Prefect UI 的 `Logs` 面板里也能看到 flow / task 日志。
|
||||
|
||||
如果 UI 没看到新日志,通常说明:
|
||||
|
||||
- worker 还没重启到最新代码
|
||||
- 或本次 run 还是旧 deployment / 旧镜像执行的
|
||||
|
||||
## 8. 常见问题
|
||||
|
||||
### 8.1 `prefect: command not found`
|
||||
|
||||
说明宿主机没有安装 Prefect CLI。
|
||||
可改为在容器里执行:
|
||||
|
||||
```bash
|
||||
docker exec -it prefect-logistics-worker sh -lc 'cd /app && prefect deploy --all'
|
||||
```
|
||||
|
||||
### 8.2 `httpx.ConnectError: All connection attempts failed`
|
||||
|
||||
说明容器里访问不到 `PREFECT_API_URL`。
|
||||
常见原因:
|
||||
|
||||
- `.env` 里的 `PREFECT_API_URL` 写成了 `localhost`
|
||||
- 容器里访问不到宿主机 Prefect API
|
||||
|
||||
当前 compose 已经加了:
|
||||
|
||||
```yaml
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
```
|
||||
|
||||
所以更推荐把 `.env` 里的 `PREFECT_API_URL` 配成类似:
|
||||
|
||||
```bash
|
||||
PREFECT_API_URL=http://host.docker.internal:4200/api
|
||||
```
|
||||
|
||||
### 8.3 飞书返回 `91403 Forbidden`
|
||||
|
||||
说明当前应用对目标多维表没有足够权限。
|
||||
需要检查:
|
||||
|
||||
- 应用是否已添加到目标 Base
|
||||
- 是否具备可编辑权限
|
||||
- 是否允许新增记录 / 删除记录 / 新增字段
|
||||
|
||||
### 8.4 没有收到飞书群通知
|
||||
|
||||
需要检查:
|
||||
|
||||
- `.env` 中是否配置了 `FEISHU_CHAT_ID`
|
||||
- 当前应用是否具备发送消息权限
|
||||
- 该应用对应机器人是否已加入目标群
|
||||
|
||||
## 9. 最推荐的执行方式
|
||||
|
||||
如果你要的是“服务器上长期稳定自动执行”,建议按这个顺序:
|
||||
|
||||
1. 构建镜像
|
||||
2. 准备 `.env`
|
||||
3. 启动 worker 容器
|
||||
|
||||
```bash
|
||||
cd /Users/idss/YXT_Project/logistics-service
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
4. 在能连到 `PREFECT_API_URL` 的环境里注册 deployment
|
||||
|
||||
```bash
|
||||
docker exec -it prefect-logistics-worker sh -lc 'cd /app && prefect deploy --all'
|
||||
```
|
||||
|
||||
5. 到 Prefect UI 检查:
|
||||
- deployment 是否已注册
|
||||
- work pool 是否是 `logistics-service-pool`
|
||||
- schedule 是否是每天 `12:00`
|
||||
Reference in New Issue
Block a user