Files
baiyue-firstleg/file/README.md
T

126 lines
5.0 KiB
Markdown
Raw Normal View History

2026-08-04 12:57:58 +08:00
# File Service 使用与运维说明
File Service 同时承载企业资质文件和公共导出下载中心。公共导出采用数据库任务表、事务 Outbox、RocketMQ 和业务 Provider;完整架构与接口契约见 [`../docs/公共导出与下载中心接入说明.md`](../docs/公共导出与下载中心接入说明.md)。
## 公共导出运行条件
创建导出任务只会写入 `file_export_task` 和 `file_export_outbox`。以下三个组件全部启用后,任务才会从 `PENDING` 继续执行:
```dotenv
FILE_EXPORT_RECONCILER_ENABLED=true
FILE_EXPORT_PUBLISHER_ENABLED=true
FILE_EXPORT_CONSUMER_ENABLED=true
FILE_EXPORT_CONSUMER_CONCURRENCY=4
```
三个开关默认均为 `false`,避免 RocketMQ 尚未就绪时 File Service 启动失败。Docker 容器只在创建时读取环境变量;修改 Jenkins 环境文件后必须重新部署 File Service,`docker restart` 不会更新配置。
当前测试环境由 Jenkins 文件凭据 `firstleg-test-env` 注入这些变量;凭据内容变更后重新执行 `file` 服务的部署阶段。
测试环境还必须配置:
```dotenv
INFRA_NETWORK=firstleg-test-infra-network
ROCKETMQ_NAME_SERVER=rocketmq-namesrv:9876
ROCKETMQ_BROKER_IP=rocketmq-broker
MQ_TOPIC_PREFIX=test-
ROCKETMQ_DATA_DIR=/data/firstleg/rocketmq/store
```
File 与 RocketMQ 不暴露 MQ 宿主机端口,二者通过 `infra-network` 和 Docker 服务名通信。`ROCKETMQ_BROKER_IP` 不得填写 `localhost`、`127.0.0.1` 或宿主机公网地址。
## 测试环境首次部署 RocketMQ
在服务器的稳定仓库目录执行,不要依赖会被 Jenkins 清理的临时工作区:
```bash
cd /www/deploy/baiyue-firstleg
mkdir -p /data/firstleg/rocketmq/store
chown -R 3000:3000 /data/firstleg/rocketmq/store
DEPLOY_ENV=test \
INFRA_NETWORK=firstleg-test-infra-network \
ROCKETMQ_BROKER_IP=rocketmq-broker \
ROCKETMQ_DATA_DIR=/data/firstleg/rocketmq/store \
MQ_TOPIC_PREFIX=test- \
docker compose -f deploy/docker-compose.rocketmq.yml up -d
```
官方 `apache/rocketmq:5.3.1` 镜像使用 UID/GID `3000` 的 `rocketmq` 用户。宿主机存储目录若属于 `root:root` 且不可写,Broker 会反复重启;不要把 Broker 改成 root 用户,应修正挂载目录所有权。
部署后的正常状态:
```text
rocketmq-namesrv Up
rocketmq-broker Up
rocketmq-topic-init Exited (0)
```
`rocketmq-topic-init` 是一次性初始化容器,`Exited (0)` 表示 Topic、消费组和 DLQ 初始化成功。
验证 Broker 注册结果:
```bash
docker run --rm \
--network firstleg-test-infra-network \
apache/rocketmq:5.3.1 \
sh mqadmin clusterList -n rocketmq-namesrv:9876
```
输出必须包含 `BaiyueCluster`、`baiyue-file-export-broker` 和可访问地址 `rocketmq-broker:10911`。
## 分阶段启用导出
首次上线按以下顺序逐步修改环境文件,每一步都重新部署 File Service 并确认容器 `healthy`、`restartCount=0`:
1. Reconciler:`true / false / false`
2. Reconciler + Publisher:`true / true / false`
3. Reconciler + Publisher + Consumer:`true / true / true`
顺序均为 `RECONCILER / PUBLISHER / CONSUMER`。第二阶段应观察到 Outbox 从 `PENDING` 变为 `SENT`;第三阶段任务应从 `PENDING` 进入 `RUNNING`,最终进入 `SUCCEEDED` 或带明确原因的 `FAILED`。已有的 `PENDING` 任务无需重建或手工改状态。
## 快速排查
任务状态查询:
```sql
SELECT id, task_no, status, dispatch_version, attempt_count,
processed_rows, next_retry_at, lease_owner, lease_until,
requested_at, started_at, completed_at, failure_message
FROM file_export_task
WHERE id = ?;
```
Outbox 查询:
```sql
SELECT id, task_id, dispatch_version, topic, status, attempt_count,
next_retry_at, lease_owner, lease_until, sent_at, last_error
FROM file_export_outbox
WHERE task_id = ?
ORDER BY id;
```
| 现象 | 判断与处理 |
|---|---|
| Task `PENDING`、`attempt_count=0`,Outbox `PENDING`、`attempt_count=0` | Publisher 未启用或未运行 |
| Outbox `PENDING` 且有 `last_error` | Publisher 已尝试,检查 NameServer、Broker、Topic 和网络 |
| Outbox `CLAIMED` 且租约过期 | Publisher 中断,确认 Reconciler 已启用 |
| Outbox `SENT`,Task 仍为 `PENDING` | Consumer 未启用、未连接或存在消费积压 |
| File 启动时报 `connect to null failed` | NameServer/Broker 未运行,或未连接同一 `infra-network` |
| Broker 反复重启,数据目录为 `root:root` | 将挂载目录递归调整为 `3000:3000`,不要使用 root 运行 Broker |
不要手工把 Task 改为 `RUNNING` 或把 Outbox 改为 `SENT`,否则会绕过租约、幂等和消息投递链路。
## 验收
测试环境主链路验收使用:
```powershell
$env:ADMIN_ACCESS_TOKEN = '<测试环境平台用户Token>'
.\scripts\export-center-test-env-acceptance.ps1 `
-GatewayBaseUrl 'http://8.163.30.128:9000'
```
脚本会创建真实 `CUSTOMER_LIST` 任务、轮询终态、下载文件并检查 XLSX ZIP 签名。Token 只通过当前进程环境变量注入,不写入仓库文件。