# 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 只通过当前进程环境变量注入,不写入仓库文件。