本文目标是让接手者从“页面报错/消息没消费/数据不对”出发,在最短路径内判断问题属于入口、运行时、配置、数据、缓存、消息还是外部系统。
命令默认用于本机 Colima 开发环境。预发与生产只做受控只读排查,不在文档中记录账号、密码、Cookie、Token、内部主机地址或客户隐私数据。
1. 业务目标
一套可用的 DGJ 本地联调环境必须证明五件事:
- 浏览器请求确实进入本地 OpenResty。
- OpenResty 把 PHP 请求交给本地
php74:9000。 - PHP 读取的是预期代码、配置和会话。
- MySQL、Redis、RabbitMQ 等依赖连接到预期环境。
- 请求能够通过业务单号或 RequestId 追到日志和数据结果。
“容器启动了”只证明进程存在,不等于业务环境正确。
2. 适用场景
| 现象 | 首先查看 |
|---|---|
dgj2.localhost 打不开 | Docker context、OpenResty、80 端口、证书/配置 |
| 502 / 504 | PHP-FPM、FastCGI、PHP fatal、外部调用超时 |
| 登录页能开,业务页跳回登录 | Session、Redis、账号状态、环境数据库 |
| 改代码不生效 | 代码挂载、分支/worktree、FPM/opcache、请求实际主机 |
| 数据库连接失败 | mysql57 状态、配置挂载、架构兼容 |
| 接口返回旧数据 | Redis/Mongo/ES 缓存与环境混用 |
| MQ 不消费 | RabbitMQ、消费者进程、destination/routing key、日志目录 |
| 本地无法收到外部回调 | 使用预发联调或受控重放,不伪造业务成功 |
| 找不到日志 | 先确认 LOGPATH 和 logger 的 logPath/channel |
| 页面与预发结果不同 | 比较代码版本、配置、数据、外部依赖和缓存五层 |
3. 项目和运行时路径
| 资源 | 路径 |
|---|---|
| DGJ2 代码 | /Users/zhoujiangbin/code/docker-dev-env/www/dgj2.0 |
| Docker 开发栈 | /Users/zhoujiangbin/code/docker-dev-env |
| Compose 主文件 | docker-compose.yml |
| Colima override | docker-compose.colima.yml |
| 标准启动脚本 | scripts/start_saas_dgj.sh |
| OpenResty DGJ 配置 | services/openresty/conf.d/dgj2.conf |
| PHP 7.4 配置 | services/php/conf/php.ini、services/php/conf/version/74/* |
| DGJ 配置挂载 | 容器内 /data/configs/dgj |
| DGJ 业务日志 | 容器内 /data/logs/dgj |
| DGJ Session | 容器内 /data/sessions/dgj |
| 上传目录 | 容器内 /data/uploads |
4. 本地运行架构
flowchart LR
B[浏览器 / curl] -->|dgj2.localhost:80| N[OpenResty]
N -->|FastCGI| P[php74 : 9000]
P --> CODE["/www/dgj2.0"]
P --> CFG["/data/configs/dgj"]
P --> DB[(mysql57)]
P --> R[(redis)]
P --> MQ[(rabbitmq)]
P --> M[(MongoDB 可选)]
P --> EXT[预发/本地外部服务]
P --> LOG["/data/logs/dgj"]
OpenResty 的 DGJ server:
server_name: dgj2.localhost
root: /www/dgj2.0
PHP upstream: php74:9000
本地 OpenResty 访问日志当前配置为关闭,错误日志在 OpenResty 容器日志目录中。因此“没有 access log”不等于请求没有到达。
5. 核心服务
| 容器 | 作用 | 必要性 |
|---|---|---|
openresty | HTTP 入口和 FastCGI 转发 | 必需 |
php74 | CodeIgniter/PHP-FPM 与 CLI 消费者 | 必需 |
mysql57 | DGJ 业务数据库 | 必需 |
redis | Session、缓存、锁、幂等 | 必需 |
rabbitmq | MQ 生产和消费 | MQ 联调必需 |
mongodb | App/OpenAPI 日志、部分商品和会话 | 对相关场景必需 |
elasticsearch | 商品搜索 | 搜索联调必需 |
kafka260 | 机器人/特定消息场景 | 对相关场景必需 |
启动 DGJ 主链只需要先拉起前五个,其他依赖按业务场景增加。
6. Docker Context
本机已经从 Docker Desktop 迁移到 Colima。命令应显式指定:
DOCKER_CONTEXT=colima docker ps
不要根据 docker ps 的空结果直接判断容器不存在;未指定 context 时可能查到默认 Docker socket。
6.1 首次体检
docker context ls
colima status
DOCKER_CONTEXT=colima docker version
DOCKER_CONTEXT=colima docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
判断:
| 输出 | 含义 |
|---|---|
| Colima running 且 client/server 都有版本 | Docker daemon 可用 |
| context 不存在但 socket 存在 | 修复 context,不要启动 Docker Desktop |
容器 Restarting | 先看容器日志,不能继续业务验证 |
容器 Exited | 检查配置、挂载、端口和证书 |
7. 标准启动
优先使用项目已有脚本:
cd /Users/zhoujiangbin/code/docker-dev-env
DOCKER_CONTEXT=colima ./scripts/start_saas_dgj.sh
只启动 DGJ 基础依赖:
cd /Users/zhoujiangbin/code/docker-dev-env
DOCKER_CONTEXT=colima docker compose \
-f docker-compose.yml \
-f docker-compose.colima.yml \
up -d php74 mysql57 redis rabbitmq openresty
start_saas_dgj.sh 还会处理 SAAS、本地域名映射、证书信任、Xdebug 配置和 MQ 日志目录,适合 DGJ/SAAS 联调。
8. 启动后的最小验收
curl -sS -o /tmp/dgj2_login.html \
-w 'HTTP %{http_code} bytes %{size_download}\n' \
--max-time 15 \
http://dgj2.localhost/index.php/passport/login/index
DOCKER_CONTEXT=colima docker exec php74 php -v
DOCKER_CONTEXT=colima docker exec php74 sh -lc \
'netstat -tlnp 2>/dev/null | grep :9000 || true'
预期:
- 登录页 HTTP 200。
- PHP 版本为项目兼容的 7.4。
- PHP-FPM 监听 9000。
- OpenResty 与 PHP 容器都在同一 Compose 网络中。
9. 五层健康检查
flowchart TD
A[请求失败] --> B{域名能访问吗}
B -->|否| C[OpenResty/端口/hosts]
B -->|是| D{PHP页面能执行吗}
D -->|否| E[FastCGI/FPM/PHP fatal]
D -->|是| F{数据库可用吗}
F -->|否| G[mysql57/配置/账号]
F -->|是| H{Session和缓存可用吗}
H -->|否| I[Redis/库号/key]
H -->|是| J{业务依赖可用吗}
J -->|否| K[MQ/Mongo/ES/外部服务]
J -->|是| L[进入业务逻辑排查]
不能跳过基础设施直接改业务代码。
10. OpenResty 排查
DOCKER_CONTEXT=colima docker ps -a --filter name=openresty
DOCKER_CONTEXT=colima docker logs --tail 200 openresty
DOCKER_CONTEXT=colima docker exec openresty openresty -t
常见问题:
| 现象 | 原因 | 处理 |
|---|---|---|
| 80 端口占用 | 另一 Nginx/Docker Desktop/本地服务 | 找到占用者,避免双栈同时启动 |
SSL key too small | 旧本地证书不兼容 | 重新生成 2048 位含 SAN 的本地证书 |
| 502 | php74:9000 不通 | 查 FPM 和容器网络 |
| 404 | root/try_files/URI 不符 | 查 dgj2.conf 和实际路径 |
| 配置测试失败 | 挂载文件语法错误 | 修复宿主机源文件再重启 |
11. PHP-FPM 排查
DOCKER_CONTEXT=colima docker ps -a --filter name=php74
DOCKER_CONTEXT=colima docker logs --tail 200 php74
DOCKER_CONTEXT=colima docker exec php74 php -m
DOCKER_CONTEXT=colima docker exec php74 php --ini
DOCKER_CONTEXT=colima docker exec php74 sh -lc 'ls -ld /www/dgj2.0 /data/configs/dgj /data/logs/dgj'
项目关键 PHP 限制来自挂载配置:
| 配置 | 当前文件基线 |
|---|---|
max_execution_time | 300 秒 |
memory_limit | 256M |
post_max_size | 100M |
upload_max_filesize | 50M |
导入、导出、报表超时时,需要同时检查 Nginx、FPM、PHP 和外部服务,不是只改一个值。
12. Xdebug
Colima override 把以下文件只读挂载进 php74:
services/php/conf/version/74/docker-php-ext-xdebug.ini
关键规则:
- Xdebug 3 使用
xdebug.mode=debug。 - 请求自动尝试连接 IDE。
- 客户端端口和宿主机名称由挂载配置指定。
- 容器内直接改 ini 会在重建后丢失,应改宿主机源文件。
检查:
DOCKER_CONTEXT=colima docker exec php74 php --ri xdebug
DOCKER_CONTEXT=colima docker exec php74 sh -lc 'tail -n 100 /tmp/xdebug.log 2>/dev/null || true'
断点不进时依次看:请求是否打到本地、Xdebug 是否加载、IDE 是否监听、路径映射是否 /www/dgj2.0。
13. 环境变量与配置优先级
CodeIgniter 环境由 CI_ENV 决定,未设置时默认为 development。
配置来源可能包括:
仓库 application/config/*.php
+ application/config/{ENVIRONMENT}/*.php(存在时优先)
+ 容器挂载 /data/configs/dgj
+ 环境变量和常量
+ 远程/中心服务配置
13.1 配置文件地图
| 配置 | 文件 |
|---|---|
| 数据库 | application/config/database.php + 外部配置挂载 |
| Redis | application/config/redis.php |
| RabbitMQ | application/config/mq.php |
| Mongo | application/config/mongodb.php |
| Elasticsearch | application/config/elasticsearch.php |
| 路由 | application/config/routes.php |
| App API | application/config/appapis.php |
| 老 OpenAPI | application/config/apis.php |
| SAAS API | application/config/SaasApis.php |
| 表常量 | application/config/tables.php |
| 功能开关/版本 | application/config/env.php、version.php 等 |
13.2 不泄密地确认环境
只输出主机别名、库名、端口和环境名,不输出密码/Token:
DOCKER_CONTEXT=colima docker exec php74 php -r '
echo "CI_ENV=".(getenv("CI_ENV") ?: "development").PHP_EOL;
echo "PHP=".PHP_VERSION.PHP_EOL;
'
数据库配置建议通过已有只读查询 Skill 验证 SELECT DATABASE(),不要直接 cat 配置文件到终端记录。
14. 六类入口
| 入口 | 定位方法 | 基类/处理器 |
|---|---|---|
| PC 页面/Ajax | 路由 + Controller 方法 | BaseController |
| App/PDA code | appapis.php | BaseAppController、App Service |
| 老 OpenAPI | apis.php + OpenService | BaseService |
| Inner API | Controller 路径 | BaseApiController |
| MQ | destination + routing key | controllers/tasks/*Notify.php |
| CLI/定时任务 | php index.php tasks/... | CLI Controller |
flowchart TD
A[拿到请求信息] --> B{入口类型}
B -->|URL| C[routes.php -> Controller]
B -->|transCode/reqCode| D[apis.php/appapis.php -> Service]
B -->|MQ event| E[MqEventEnums -> tasks Consumer]
B -->|CLI| F[tasks Controller method]
C --> G[Service -> Model/Provider]
D --> G
E --> G
F --> G
15. PC 请求定位
rg -n "目标路径|目标方法" application/config/routes.php application/controllers
rg -n "function 目标方法" application/controllers
rg -n "目标Service|目标Model" application/controllers application/Services application/service
PC 请求常依赖登录 Session、站点 sid、用户 uid、菜单权限和账号状态。未登录 curl 与浏览器登录请求不能直接比较。
15.1 浏览器复现记录
保留:
请求 URL、方法、Content-Type、状态码、耗时、业务 code/message、RequestId、sid、业务单号、请求时间
Cookie 和完整请求头只保存在受控本地环境,不贴进文档或群聊。
16. App / PDA 请求定位
BaseAppController:
- 读取 JSON body。
- 根据
reqCode选择appApi/app或pdaApi/app日志。 - 记录 URI 与请求体。
- 校验
sign、data、reqCode、uid。 - 校验签名、登录和设备。
- 合并业务数据与用户上下文。
- 尝试写 Mongo
dgj_app_log。
sequenceDiagram
participant C as App/PDA
participant A as BaseAppController
participant L as 文件日志
participant M as Mongo dgj_app_log
participant S as 业务Service
C->>A: JSON reqCode/uid/sign/data
A->>L: URI + request_body
A->>A: 参数/签名/登录/设备校验
A->>M: 请求与用户上下文
A->>S: businessData
S-->>C: 业务响应
16.1 安全债
旧签名实现包含硬编码共享签名材料。文档不记录其值;维护建议:迁移到配置中心、支持轮换和版本、避免在签名失败消息中回显签名。
17. 老 OpenAPI 定位
OpenService 处理 transCode:
apis.php 映射 -> application/service/api/{path}.php -> BaseService::service
请求有 requestId 时:
- Redis 使用 NX + 10 分钟 TTL 防并发重复。
- Mongo
dgj_api_log保存请求和处理状态。 - 处理成功后把日志状态改为成功。
flowchart TD
A[OpenAPI 请求] --> B[校验 transCode/reqCode/targetCode]
B --> C{有 requestId}
C -->|是| D[Redis 10分钟请求锁]
D --> E[Mongo dgj_api_log]
C -->|否| F[直接映射 Service]
E --> F
F --> G[业务执行]
G --> H[更新 Mongo status]
G --> I[释放请求锁]
重复请求排查必须同时看 Redis 锁和 Mongo 状态,不能只重发。
18. Inner API 定位
BaseApiController 支持 JSON 和表单,读取 Request-Id、Shipper、Inspire-Api-User 等头,并记录 URI、body、header。
安全注意:当前日志会记录完整 header/body,联调时必须对内部 Token、用户信息和文件 URL 脱敏。
常用日志:
/data/logs/dgj/inner/api-YYYY-MM-DD.log
实际文件名由 Monolog RotatingFileHandler 生成,以环境中的文件为准。
19. MQ 入口定位
rg -n "事件名" application/KzData/Enums/MqEventEnums.php
rg -n "事件名|registryCallback" application/controllers/tasks
rg -n "事件名|send.*Mq|publish" application/Services/Mq/MqSer.php application/Services/SyncOrder
消费者启动形态:
DOCKER_CONTEXT=colima docker exec -it php74 \
php /www/dgj2.0/index.php tasks/OrderCenterNotify/consume
替换为目标 Controller。启动前必须确认连接的是本地/开发 RabbitMQ,避免本地消费者误消费预发或生产消息。
20. CLI / 定时任务定位
DOCKER_CONTEXT=colima docker exec php74 \
php /www/dgj2.0/index.php tasks/FlashSaleTask/refreshGoodsStatus
执行前:
- 阅读方法确认参数和默认范围。
- 确认数据库、Redis、MQ 环境。
- 对批量任务先找 dry-run、分页或单 ID 参数。
- 记录开始/结束时间和影响行数。
- 不在生产直接运行本地未经审核的任务。
21. 日志体系总览
| 层 | 位置 | 用途 |
|---|---|---|
| OpenResty error | 容器 /var/log/nginx/nginx.dgj2.error.log | 502、配置、FastCGI |
| PHP/FPM | 容器 /var/log/php、docker logs php74 | Fatal、扩展、FPM |
| CodeIgniter | LOGPATH 下框架日志 | 框架错误,阈值当前偏错误级 |
| Monolog | LOGPATH/{logPath}/{channel}-日期.log | 业务、Provider、Consumer |
| Mongo App 日志 | dgj_app_log | App/PDA 请求 |
| Mongo OpenAPI 日志 | dgj_api_log | 请求幂等和处理状态 |
| MQ SDK 日志 | /data/logs/kzmq/* | Producer/Consumer 传输 |
| Kibana | logstash-YYYY-MM-DD | 预发/生产集中日志 |
22. LOGPATH 规则
index.php 按操作系统定义:
| 运行方式 | LOGPATH |
|---|---|
| Linux/Darwin | /data/logs/dgj |
| Windows | application/logs |
本地 PHP 运行在 Linux 容器中,所以日志写 /data/logs/dgj,该目录由 Compose 挂载到宿主机数据目录。直接看仓库 application/logs 通常只能看到占位文件。
23. Monolog 文件规则
调用:
KzLogger::getLogger($logPath, $channel)
目标:
LOGPATH/{logPath}/{channel}.log
由于使用 RotatingFileHandler,实际落盘会带日期后缀。每行格式:
[时间][级别][channel] RequestId#...# 消息 context
常用目录:
| 目录 | 内容 |
|---|---|
providers/ | 外部 HTTP 调用 |
inner/ | Inner API、机器人、账户等 |
appApi/ | App 请求 |
pdaApi/ | PDA 请求 |
OrderCenterNotify/ | 订单中心回调 |
PayCenterNotify/ | 支付回调 |
robot_v2/ | IM/机器人 V2 |
debug/ | 历史调试日志,谨慎使用 |
24. RequestId
KzLogger 默认生成 16 位随机 RequestId;KzLoggerInstance 自动在每条消息前加:
RequestId#{requestId}#
部分 Inner API 从 Request-Id header 读取,但必须调用 KzLogger::setRequestId 才能保证所有 logger 统一。异步回调可使用强制同步已创建 logger 的模式。
flowchart LR
A[网关/调用方 Request-Id] --> B[Controller 读取]
B --> C[KzLogger::setRequestId]
C --> D[Controller 日志]
C --> E[Service 日志]
C --> F[Provider 日志]
C --> G[MQ payload/headers]
当前并非所有链路都完成 RequestId 透传,排查时仍需组合业务单号、sid、事件名和时间窗口。
25. 日志搜索顺序
1. 业务单号/支付流水/任务号。
2. RequestId / traceId / messageId。
3. sid + 精确时间窗口。
4. Controller/Consumer/Provider channel。
5. 错误文案。
本地示例:
DOCKER_CONTEXT=colima docker exec php74 sh -lc \
'rg -n "业务单号|RequestId#目标ID#|错误文案" /data/logs/dgj 2>/dev/null | tail -n 120'
若容器没有 rg,改用限定目录和关键词的 grep -R,避免扫整个磁盘。
26. Provider 日志
BaseProvider 默认记录 URL、headers、data 和响应,并生成一次本地请求 ID。
排查外部调用:
业务请求日志 -> Provider 请求日志 -> Provider 响应/异常 -> 下游日志 -> 回调日志
风险:请求头、Token、手机号、银行卡、UserSig 等可能进入日志。查询和分享前必须脱敏。
27. 数据库联调
优先使用统一只读脚本:
php /Users/zhoujiangbin/.codex/skills/dgj-sql-query-runner/scripts/query_dgj_sql.php \
--env dev \
--sql "SELECT 1"
27.1 分表
查询前从 Model/常量确认:
物理表 = 基础表名 + '_' + sid % 分片数
常见分片数包括 16、32、64、128,不能凭记忆猜后缀。
rg -n "SUB_NUM|%.*sid|setSubTable|tableName" application/models application/config/tables.php
27.2 数据证据链
flowchart LR
A[主单] --> B[业务明细]
B --> C[库存/资金流水]
C --> D[实时结果]
A --> E[MQ/外部单号]
E --> F[下游状态]
C --> G[报表/DWD]
不要只查一张主表就下结论。
28. MySQL 容器排查
DOCKER_CONTEXT=colima docker ps -a --filter name=mysql57
DOCKER_CONTEXT=colima docker logs --tail 200 mysql57
DOCKER_CONTEXT=colima docker inspect mysql57 --format '{{.State.Status}} {{.State.ExitCode}} {{.State.Error}}'
若持续 Restarting:
- 看最后一次退出错误。
- 检查 Colima 磁盘空间。
- 检查数据卷权限和 MySQL 5.7 架构兼容。
- 不删除数据卷,不执行重建数据目录。
- 必要时先做只读备份/恢复评估。
29. Redis 联调
Redis 承担:Session、权限缓存、商品集合、请求锁、任务锁、活动购物车等。
安全查询:
DOCKER_CONTEXT=colima docker exec redis redis-cli PING
DOCKER_CONTEXT=colima docker exec redis redis-cli INFO keyspace
DOCKER_CONTEXT=colima docker exec redis redis-cli --scan --pattern '明确前缀*' | head
禁止:
KEYS *
FLUSHALL / FLUSHDB
对未知 key 直接 DEL
把真实 session/token 值贴到文档
29.1 Request 锁
老 OpenAPI 使用 requestId 的 Redis NX 锁,TTL 10 分钟。若请求失败后立即重试提示重复,需要判断锁是否应由正常回调释放,不能直接删 key 掩盖业务未完成。
30. Session 排查
PC 登录依赖 Session 和 Redis/文件配置。跳回登录时检查:
1. 浏览器 Cookie 是否属于 dgj2.localhost。
2. PHP 读取的 SESSION_PATH/Redis 库是否正确。
3. sid/uid/role/login 字段是否完整。
4. 账号、门店、菜单权限是否可用。
5. 是否命中维护、逾期锁站或安全状态。
6. OpenResty 与 PHP 的 Host/HTTPS 判断是否一致。
不要把预发 Cookie 复制进本地长期使用。
31. RabbitMQ 联调
基础检查:
DOCKER_CONTEXT=colima docker exec rabbitmq rabbitmq-diagnostics ping
DOCKER_CONTEXT=colima docker exec rabbitmq rabbitmqctl list_queues name messages consumers
DOCKER_CONTEXT=colima docker exec rabbitmq rabbitmqctl list_bindings source_name destination_name routing_key
31.1 消费者不工作
flowchart TD
A[消息未消费] --> B{RabbitMQ可用}
B -->|否| C[容器/磁盘/配置]
B -->|是| D{队列有消费者}
D -->|否| E[启动正确CLI Consumer]
D -->|是| F{binding命中}
F -->|否| G[核对destination/routing key]
F -->|是| H{消息反复重投}
H -->|是| I[查NACK异常和前置数据]
H -->|否| J[查ACK后业务事务/幂等]
消息重放前保存原 payload、messageId、routing key、headers 和原消费结果。
32. MQ 日志目录
启动脚本会准备:
/data/logs/kzmq/producer/inspiremq.topic
如果 Producer 因日志目录权限失败:
DOCKER_CONTEXT=colima docker exec php74 sh -lc \
'mkdir -p /data/logs/kzmq/producer/inspiremq.topic && chmod -R 0777 /data/logs/kzmq'
0777 是当前本地兼容处理,不应直接复制到生产权限设计。
33. Mongo 联调
相关集合:
| 集合 | 用途 |
|---|---|
dgj_app_log | App/PDA 请求日志 |
dgj_api_log | 老 OpenAPI 请求和状态 |
| 每站商品集合 | 商品搜索/缓存 |
| 机器人会话集合/表 | 具体实现按版本确认 |
查询要求:
- 按
requestId、业务单号、时间窗口和 sid 限定。 - 不导出完整请求头、签名和用户隐私。
- “Mongo 写失败被 catch”时,文件日志可能有请求但集合没有记录。
34. Elasticsearch 联调
检查顺序:
索引存在 -> mapping -> 文档存在 -> refresh -> 查询 DSL -> 站点查询开关 -> 前端缓存
只读命令示意:
curl -sS 'http://本地ES/_cat/indices?v'
curl -sS 'http://本地ES/索引/_search' \
-H 'Content-Type: application/json' \
--data '{"size":1,"query":{"term":{"sku_id":"目标SKU"}}}'
实际地址从配置读取,不把线上地址写入命令记录。
35. 外部系统本地联调
本地通常无法自然收到支付中心、订单中心、OA、调拨中心等回调。
选择顺序:
- 使用系统官方开发/预发环境完成真实联调。
- 使用已有 Consumer 的受控
resend/test方法,先阅读实现。 - 用本地 RabbitMQ 发送脱敏、唯一的测试消息。
- 对纯查询接口使用 Mock。
- 不直接调用业务回调方法伪造已支付/已出库结果,除非测试数据完全隔离且有回滚方案。
36. Mock 原则
| 可以 Mock | 不应随意 Mock |
|---|---|
| 商品只读查询 | 真实支付成功 |
| 地址解析 | 真实退款完成 |
| 报表只读响应 | 库存正式扣减/释放 |
| AI/OCR 结果 | OA 正式审批 |
| 通知发送 | 外部订单受理状态 |
Mock 必须覆盖成功、明确失败、超时、空响应和字段缺失,不是只返回固定成功。
37. 代码改了不生效
flowchart TD
A[改动不生效] --> B{请求打到本地吗}
B -->|否| C[域名/代理/Host/浏览器环境]
B -->|是| D{容器看到新文件吗}
D -->|否| E[检查SOURCE_DIR挂载]
D -->|是| F{当前分支/worktree正确吗}
F -->|否| G[定位真实代码目录]
F -->|是| H{FPM/opcache缓存}
H -->|是| I[安全重启php74/openresty]
H -->|否| J[查路由开关和新旧服务分流]
检查:
pwd
git branch --show-current
git status --short
DOCKER_CONTEXT=colima docker exec php74 sh -lc \
'stat /www/dgj2.0/目标文件.php && rg -n "新代码特征" /www/dgj2.0/目标文件.php'
38. 404 排查
1. 请求 Host 是否是 dgj2.localhost。
2. OpenResty root 是否 `/www/dgj2.0`。
3. URI 是否需要 `/index.php/`。
4. `routes.php` 是否有显式路由。
5. Controller 文件、类名、方法名大小写是否匹配。
6. App/OpenAPI 是否通过 code 映射,而不是直接 URL 方法。
7. 新旧服务转发开关是否把请求转走。
39. 500 / Fatal 排查
DOCKER_CONTEXT=colima docker logs --tail 200 php74
DOCKER_CONTEXT=colima docker exec php74 sh -lc \
'find /data/logs/dgj -type f -mmin -10 -print | xargs -r tail -n 80'
优先看第一条 fatal 的文件和行号,不要被后续 502、空响应或前端 JSON 解析错误带偏。
40. 502 / 504 排查
| 状态 | 常见原因 |
|---|---|
| 502 | FPM 未监听、容器网络、PHP 进程崩溃、FastCGI 配置 |
| 504 | PHP 执行过久、外部接口超时、数据库慢查询、导入导出大文件 |
时间线:
OpenResty 时间 -> PHP 请求开始 -> SQL/Provider 开始 -> 外部返回/超时 -> PHP 响应
用 RequestId 对齐每段耗时。
41. 数据不对排查
1. 确认环境和 sid。
2. 确认业务主键和分表。
3. 查主单与明细状态。
4. 查库存/资金过程流水。
5. 查实时结果表。
6. 查 Redis/Mongo/ES 缓存。
7. 查 MQ/外部系统状态。
8. 查报表同步时点。
不要把缓存清除当成数据修复。
42. 日志找不到排查
flowchart TD
A[没有日志] --> B{代码走到 logger 吗}
B -->|否| C[入口/路由/前置校验]
B -->|是| D{LOGPATH 是哪里}
D --> E["/data/logs/dgj"]
E --> F{logPath/channel正确吗}
F -->|否| G[按 KzLogger 调用反查]
F -->|是| H{目录权限/日期后缀}
H --> I[容器挂载和 RotatingFileHandler]
反查命令:
rg -n "KzLogger::getLogger\(" application/目标目录
43. 请求成功但无业务变化
可能原因:
- 业务响应只表示“已受理”。
- 本地事务回滚但 Controller 仍包装了旧响应。
- 幂等判断提前返回。
- 事件进入延迟队列。
- 外部副作用失败。
- 写入了另一个 sid 的分表。
- 代码走了新微服务而不是本地 Service。
必须对照主单、明细、流水、消息、外部单号五层证据。
44. MQ 消费成功但数据不对
1. 确认 ACK 是业务成功还是“不可重试错误也 ACK”。
2. 查消息 payload 和业务版本。
3. 查幂等记录是否把新消息当重复。
4. 查原状态是否合法。
5. 查事务提交状态。
6. 查事务后的库存/资金/MQ 副作用。
7. 查乱序消息是否覆盖新状态。
45. 本地与预发差异矩阵
| 维度 | 本地 | 预发 |
|---|---|---|
| 代码 | 当前工作区 | 已部署分支/构建 |
| 数据库 | 本地或显式选择环境 | 共享预发数据 |
| Redis/MQ | 可本地隔离 | 多服务共享 |
| 外部回调 | 通常不自然到达 | 可真实联调 |
| 日志 | 容器文件/Mongo | 远程文件/Kibana |
| 并发 | 单人低并发 | 多人、多实例 |
| 定时任务 | 通常手动 | 可能真实运行 |
复现差异前先把这六项填完整。
46. 预发请求日志
预发页面请求可能只是 DGJ 网关入口,真实错误来自拆分后的采购/销售服务。
排查顺序:
页面路径 -> 本地代码映射 Provider -> DGJ provider 日志 -> 下游 request/provider 日志 -> request_id -> 响应
使用现有 Skill:
dgj-preprod-request-log-inspector
preprod-log-inspector
kz-bastion-log-inspector
远程查询只读,不在知识库保留主机账号和凭据。
47. Kibana
使用 kibana-log-query-runner,按绝对时间、关键词和 RequestId 查询 logstash-YYYY-MM-DD。
推荐关键词组合:
业务单号 + event/routing key + RequestId + Controller/Provider 名
查询结果只总结时间、host、source、事件和错误,不复制完整 Cookie、Token 和大响应体。
48. 时间与时区
项目在 index.php 设置 Asia/Shanghai。Kibana、数据库、MQ header 和外部系统可能使用 UTC 或毫秒时间戳。
每次排查记录:
用户看到的时间 + 时区
DGJ 日志时间 + 时区
数据库 createTime/modifyTime
MQ occurredAt / broker 时间
外部系统时间
不要用模糊的“刚才”“下午”跨系统找日志。
49. Git 与分支安全
git branch --show-current
git status --short
git log -1 --oneline
git diff -- 目标文件
规则:
- 不覆盖用户未提交改动。
- 不在 staging 分支直接提交业务改动。
- 确认实际运行目录不是另一个 worktree。
- 合并前检查公共文件影响面。
- 不用
git reset --hard、checkout --清理未知改动。
50. PHP 基础验证
DOCKER_CONTEXT=colima docker exec php74 \
php -l /www/dgj2.0/application/目标文件.php
DOCKER_CONTEXT=colima docker exec php74 \
php /www/dgj2.0/index.php 目标CLI入口
项目没有统一覆盖所有业务的自动化测试框架时,至少完成:语法、接口正常样本、异常样本、数据库断言、日志和副作用核对。
51. 联调样本规范
每个样本记录:
环境:local/dev/staging
代码分支和 commit:
业务 sid:
业务单号/活动ID/任务号:
请求时间:
RequestId/traceId/messageId:
入口 URL/transCode/event:
请求摘要(脱敏):
预期状态:
实际响应:
数据库证据:
缓存/MQ/外部证据:
是否需要清理:
52. 一次完整联调流程
sequenceDiagram
participant D as 开发者
participant H as 本地HTTP/MQ入口
participant L as DGJ日志
participant DB as MySQL/Redis/Mongo
participant E as 外部系统
D->>D: 确认context/分支/配置
D->>H: 发唯一测试请求
H->>L: 记录RequestId和业务键
H->>DB: 事务/缓存/锁
H->>E: HTTP或MQ
E-->>H: 响应/回调
H->>DB: 最终状态和副作用
D->>L: 按RequestId核对时间线
D->>DB: 只读核对主单、明细、流水
D->>D: 清理测试数据或保留证据
53. 安全要求
| 风险 | 要求 |
|---|---|
| 生产配置混入本地 | 配置切换可逆,运行时验证目标环境 |
| 日志泄密 | Token、Cookie、签名、手机号、银行卡、UserSig 脱敏 |
| 本地消费生产 MQ | 启动 Consumer 前确认 broker |
| 直接改线上数据 | 默认只读,修复需审核和回滚 |
| Redis 全库操作 | 禁止 KEYS/FLUSH,按前缀和业务键 |
| 测试支付/退款 | 使用隔离测试单和官方测试通道 |
| 重放消息 | 先验证业务幂等,保留原消息 |
| 调试开关 | 不把 debug 绕签名/绕权限带入生产 |
54. 已确认代码风险
| 等级 | 风险 | 影响 |
|---|---|---|
| P0 | 旧 App 签名材料硬编码 | 无法安全轮换,源码泄露影响大 |
| P1 | BaseApp/Inner/Provider 记录完整请求和 header | 敏感信息进入日志 |
| P1 | App Mongo 日志写失败被空 catch | 文件有请求但 Mongo 无证据,且无告警 |
| P1 | 多套 RequestId 生成/读取未统一透传 | 跨服务追踪断链 |
| P1 | OpenResty access log 关闭 | 入口命中需靠错误日志/应用日志/临时观测 |
| P2 | CI log_threshold=1 | 框架层信息日志有限,依赖 Monolog |
| P2 | 本地 MQ 日志目录依赖宽权限初始化 | 重建容器后可能再次失败 |
| P2 | 本地与预发外部依赖混合 | 测试污染和结果不可复现 |
55. 环境故障修复边界
以下情况优先修环境,不改 DGJ 业务代码:
- OpenResty 证书不兼容。
- PHP 扩展/Xdebug ini 语法错误。
- MySQL 容器无法启动。
- Docker context 指向错误 daemon。
- 日志目录/Session 目录权限错误。
- 容器内 hosts 未映射本地域名。
以下情况才进入业务代码:
- 请求已到正确 Controller,参数和环境正确。
- 业务表/缓存/消息证据指向逻辑错误。
- 相同数据可稳定复现。
- 已排除外部服务和同步延迟。
56. 日常体检命令
cd /Users/zhoujiangbin/code/docker-dev-env
DOCKER_CONTEXT=colima docker ps --format \
'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
curl -sS -o /dev/null -w 'DGJ %{http_code} %{time_total}s\n' \
--max-time 10 \
http://dgj2.localhost/index.php/passport/login/index
DOCKER_CONTEXT=colima docker exec redis redis-cli PING
DOCKER_CONTEXT=colima docker exec rabbitmq rabbitmq-diagnostics ping
DOCKER_CONTEXT=colima docker exec php74 php -v
如果任一项失败,先处理对应基础层,再开始业务联调。
57. 常用代码检索
# URL / Controller
rg -n "目标路径|目标方法" application/config/routes.php application/controllers
# App / OpenAPI 映射
rg -n "目标code" application/config/appapis.php application/config/apis.php application/config/SaasApis.php
# MQ
rg -n "事件名" application/KzData/Enums/MqEventEnums.php application/controllers/tasks application/Services/Mq
# 日志文件归属
rg -n "KzLogger::getLogger|RequestId" application/目标目录
# 表和分片
rg -n "表常量|SUB_NUM|setSubTable" application/config/tables.php application/models
# 外部 Provider
rg -n "目标路径|requestSer|requestSerAsync" application/Providers application/Services
58. 故障报告模板
现象:
环境 / Docker context:
分支 / commit:
入口与请求时间:
sid / 业务单号:
RequestId / messageId:
HTTP 状态与业务 code:
第一条错误日志:
Controller -> Service -> Model/Provider:
数据库/缓存/MQ证据:
外部系统证据:
已排除项:
根因:
修复:
补偿:
回归:
遗留风险:
59. 回归矩阵
| 层 | 必测 |
|---|---|
| HTTP | 200、404、500、超时、登录失效 |
| 参数 | JSON、表单、空字段、非法签名、重复 requestId |
| 数据库 | 正常、无记录、分表、事务回滚、重复键 |
| Redis | 命中、未命中、锁冲突、TTL、连接失败 |
| MQ | 正常、重复、乱序、NACK、延迟、死信 |
| 外部 HTTP | 成功、业务失败、超时、空响应、部分成功 |
| 日志 | RequestId 连贯、错误可见、敏感字段脱敏 |
| 多环境 | 本地/预发配置与数据不混用 |
60. 发布前检查清单
- [ ] Docker context 明确为 Colima。
- [ ] OpenResty、php74、mysql57、redis、rabbitmq 均健康。
- [ ] 登录页和目标接口都命中本地代码。
- [ ] 当前分支、commit、dirty files 已记录。
- [ ] PHP 容器能看到最新文件。
- [ ] 数据库、Redis、MQ、外部服务环境已逐项确认。
- [ ] 请求使用唯一测试业务键。
- [ ] RequestId/业务单号能定位 Controller、Service、Provider/Consumer 日志。
- [ ] 主单、明细、流水、缓存、MQ、外部状态已核对。
- [ ] 重复、乱序、超时和回滚场景已测试。
- [ ] 日志和截图中没有 Cookie、Token、签名或客户隐私。
- [ ] 测试数据已清理或标记。
- [ ] 不需要的本地 Consumer 已停止。
- [ ] 环境改动有切回方法。
61. 证据文件
| 主题 | 代码/配置证据 |
|---|---|
| 环境、LOGPATH | index.php |
| CI 日志阈值 | application/config/config.php |
| Monolog 与 RequestId | application/Components/KzLogger.php、KzLoggerInstance.php |
| PC/Inner/GPDA | application/core/BaseController.php |
| App/PDA 日志与校验 | application/core/BaseAppController.php |
| OpenAPI 幂等 | application/service/OpenService.php、application/core/BaseService.php |
| Docker 服务和挂载 | docker-compose.yml、docker-compose.colima.yml |
| OpenResty 路由 | services/openresty/conf.d/dgj2.conf |
| 启动和本地修复 | scripts/start_saas_dgj.sh |
| 路由和接口映射 | application/config/routes.php、appapis.php、apis.php |
| MQ 入口 | application/KzData/Enums/MqEventEnums.php、application/controllers/tasks/* |
62. 待补齐
- 一键输出容器、HTTP、PHP、DB、Redis、RabbitMQ 和日志目录健康状态的脚本。
- 统一从 HTTP header 到 Service、Provider、MQ 和下游的 traceId。
- BaseApp、BaseApi 和 BaseProvider 的集中日志脱敏器。
- 本地 Mock Server 和可复用的订单/支付/配送契约样本。
- 每类 Consumer 的本地启动清单和进程守护方式。
- Mongo/ES/Kafka 按业务场景启动的标准脚本。
- OpenResty 可按需开启的脱敏 access log。
- 本地测试数据命名、隔离和清理规范。
63. 一句话记忆
先证明请求进入了正确的本地代码和正确的环境,再用 RequestId + sid + 业务单号串联日志、主明细、缓存、消息和外部状态;没有这条证据链,就不要急着改代码或改数据。
请求-日志-数据变更追踪卡
多入口请求链路
| 场景 | 调用方与入口 | 请求载荷/上下文 | Controller/Consumer | Service/Provider | 汇合点 | 最终业务事实 |
|---|---|---|---|---|---|---|
| Web/PC 联调 | 浏览器/curl | host、URI、cookie/session、form/JSON | 路由目标 Controller | 领域 Service | request ID + 业务单号 | 本地 DB 业务事实 |
| Inner/App/OpenAPI | curl/调用方服务 | header/signature/API code、sid | BaseApi/App/OpenAPI | 适配 Service | 外部/来源单号 | 与 PC 共用领域事实 |
| MQ/CLI | Broker/命令行 | destination/event/message;task 参数 | tasks/*Notify/Task | Consumer/补偿 Service | message/task ID | 异步状态和副作用 |
| 外部服务 | 本地 Provider | 本地单号、请求参数 | 调用方 | BaseProvider 子类 | request ID + 外部单号 | 外部受理与回调 |
日志证据矩阵
| 链路段 | 日志来源 | 可检索锚点 | 成功信号 | 失败信号 | 与下一段关联方式 | | --- | --- | --- | --- | --- | --- | --- | | 环境/路由 | Web 访问日志、CI_ENV、routes/apis/appapis | host、URI、API code、request_id | 命中本地目标方法 | 请求去了错误容器/环境/路由 | 类方法进入应用日志 | | 应用 | LOGPATH/application/logs、KzLogger | request ID、sid、业务单号、类方法 | Service 完成/commit | exception、rollback、错误码 | 单号查数据库 | | 数据库/缓存 | SQL 慢错日志、只读查询、Redis/ES | PK、单号、cache key/index | 主明细和派生值一致 | 表/库/分片错、缓存旧 | 业务键进入 MQ/Provider | | MQ/外部 | Consumer/Provider 两端日志 | message ID、routing key、外部 request/order ID | ACK/对方成功/回调完成 | NACK、timeout、对方未收到 | 外部键映射本地单号 |
环节数据变更台账
| 步骤 | 代码位置 | 事务 | 读取事实 | 写入表/缓存/MQ | 字段或数量变化 | 回查证据 |
|---|---|---|---|---|---|---|
| 确认环境 | config/env/database/redis/mq | 事务外 | CI_ENV、容器、host、配置名 | 无 | 零业务变化 | 进程环境、只读连接目标 |
| 重放请求 | 目标 Controller | 事务外到业务事务 | 脱敏请求、header、用户站点 | 请求日志 | 输入 -> 标准上下文 | curl 响应、request ID |
| 业务落库 | 目标 Service | 本地事务 | 旧状态/数量/金额 | 主明细/流水 | old -> new 或失败 0 写入 | 前后 SQL 快照、影响行数 |
| 异步传播 | MqSer/Provider/Consumer | commit 后 | 新业务事实 | MQ/外部/缓存 | 派生状态逐步追平 | 消息/外部 ID、ACK、回调 |
| 清理测试 | 领域撤销/反向流程 | 独立事务 | 测试业务最终态 | 反向单/关闭状态 | 通过业务动作恢复,不直接删关键流水 | 原单与反向单、库存资金平衡 |
子模块追踪:local-start 本地容器启动与健康检查
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 启动体检 | Docker/Colima 启动 DGJ2 | container/service、port、CI_ENV | application/config/env.php、application/config/config.php | 容器、OpenResty/PHP-FPM、挂载、配置环境名 | 环境检查事务外,业务 DB 不写 | container status + health URL + access/error log | 502 分层查代理、FPM、挂载;不通过改业务代码规避环境问题 |
| 最小验收 | 首页/健康接口和 PHP 语法 | URI、request ID | application/core/BaseController.php | 路由、session、日志目录和 DB 只读连接 | 请求只读 不写 | HTTP code + request ID + PHP error log | 环境未通不执行有副作用联调;修复后重跑五层健康检查 |
子模块追踪:local-pc PC 请求联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 复现请求 | 浏览器/curl 调 /scm/* | method、URI、session、sid、billNo | application/core/BaseController.php | 路由、登录、权限、query/form/JSON 和当前业务态 | 校验外零写;目标 Service 本地事务 old -> new | access request ID + URI + user/sid + billNo | 401/403/404/500 分层定位;超时按 billNo 查是否已提交 |
| 结果回查 | 响应后核对业务事实 | request ID、返回单号 | application/Components/KzLogger.php | Controller/Service 日志、主明细和后置 MQ | 查询只读 不写 | request ID + billNo + affected rows | HTTP 200 仍判断业务码;用领域撤销清理测试数据 |
子模块追踪:local-app-pda App 与 PDA 请求联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 网关/直连 | tradeCode 或 PDA Controller 请求 | tradeCode/URI、token、sid、设备业务键 | application/config/appapis.php -> application/core/BaseAppController.php | code 映射、登录上下文、载荷形态和目标类 | 路由鉴权不写;领域本地事务 old -> new | request ID + tradeCode/URI + sid + billNo | code 未映射与直连协议分开查;禁止互换接口猜测 |
| 扫码重试 | PDA 出入库/盘点响应不确定 | device request、billNo、SKU/location | application/core/BaseAppController.php | 业务单、库存流水和当前状态 | 回查只读;确认未执行才重试 | request ID + billNo + SKU + transType | 网络超时先查流水,避免重复库存;敏感 token 不写文档 |
子模块追踪:local-openapi 老 OpenAPI 联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 动态分发 | 外部请求 transCode | appId、timestamp、requestId、来源单 | application/config/apis.php -> application/service/OpenService.php | 签名、时间窗、code 映射、幂等和载荷 | 鉴权失败零写;目标 API 本地事务写业务事实 | request ID + transCode + external/local orderNo | 200 仍判断业务码;日志脱敏,不保存凭证 |
| 重复/超时 | 相同来源请求重放 | requestId、sourceOrderNo | application/service/OpenService.php | 既有映射、主单和副作用 | 已完成 new -> new,新增单据/流水 0 | old/new request IDs + sourceOrderNo | 先按来源单回查;只补缺失回调或响应,不重复建单 |
子模块追踪:local-inner Inner API 联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 内部请求 | /inner/* 服务间调用 | URI、内部头、sid、JSON、业务 ID | application/config/routes.php -> application/core/BaseService.php | 路由、内部身份、用户/站点上下文和参数 | 校验外零写;Service 本地事务 old -> new | request ID + URI + sid + business ID | 本地 mock 身份不等于预发合同;未授权零业务写入 |
| 响应验收 | success/code/data 返回 | request ID、业务 ID | application/core/BaseService.php | Service 返回、异常和持久化结果 | 响应阶段 DB 不变;异步链另查 | request ID + business code + affected rows | 成功响应后回查主表;失败仅清理本次测试事实 |
子模块追踪:local-mq RabbitMQ 消费联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 启动消费 | CLI 启动目标 Notify | destination、routing key、event | application/config/mq.php -> application/KzData/Enums/MqEventEnums.php | Broker 配置名、binding、消费者进程和 handler | 启动本身不写业务 DB | process PID + destination/routing + startup log | 队列/凭证只引用配置键;进程不工作先查 CLI 和 binding |
| 消息验收 | 发布脱敏测试消息 | message ID、稳定业务键 | application/Services/Mq/MqSer.php | 当前业务态、幂等行、ACK/NACK | 单消息本地事务 old -> new;ACK 不属于 DB 事务 | message ID + event + billNo + ACK | 重投前查业务事实;已完成重放副作用 0 |
子模块追踪:local-cli CLI 与定时任务联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 任务执行 | PHP CLI 调 tasks/method | task、参数、time window、limit | application/controllers/tasks/FlashSaleTask.php | is_cli、候选状态、时间和批量上限 | 每记录本地事务 old -> new,或 dry/query 只读 | task + batch + scanned/success/fail IDs | 本地先小批且使用测试数据;禁止无范围跑环境全量 |
| 幂等重跑 | 中断/补偿任务再次执行 | batch、business IDs | application/controllers/tasks/GoodsEsCache.php | 已完成项、失败项、锁和水位 | 已完成影响行 0;只补失败项 | task + batch + affected rows | 清锁前确认进程;水位不越过失败数据 |
子模块追踪:local-data MySQL、Redis、Mongo 与 ES 联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 连接定位 | 本地四类数据组件检查 | environment、db/index/key/collection | application/config/database.php、application/config/redis.php、application/config/mongodb.php、application/config/elasticsearch.php | 实际连接目标、分片规则和只读样本 | 健康检查只读 不写 | config name + ping/query result + target type | 不输出密码;环境目标不确定时停止写入测试 |
| 跨层核对 | 页面数据不一致 | sid、SKU/billNo、cache/index key | application/config/tables.php | MySQL 主事实、Redis/Mongo/ES 派生值和时间 | 查询只读;修复只更新明确失败派生层 old -> source | business key + each-layer timestamp | 主库为权威;禁止用缓存反写业务主表 |
子模块追踪:local-provider 外部 Provider 与 Mock 联调
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 请求构造 | 本地业务调用外部系统 | provider/endpoint、request ID、业务单 | application/Providers/BaseProvider.php | 环境 base URL、超时、脱敏 payload 和响应合同 | 外部调用事务外;mock 不写真实外部系统 | request ID + provider + latency + HTTP/business code | Mock 固定成功/失败/超时样本;不伪造生产已受理证据 |
| 回调模拟 | 模拟外部回调/乱序/重复 | event、message ID、business key | application/Services/Mq/MqSer.php | 本地当前态和幂等事实 | 单回调本地事务;重复/乱序零非法副作用 | message IDs + business key + row count | 回归成功、重复、迟到、失败四条;凭证仅用本地配置 |
子模块追踪:preprod-log 预发日志、Kibana 与环境差异
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 日志串查 | 预发接口/MQ/任务异常 | absolute time、request/message ID、billNo、sid | application/Components/KzLogger.php | 访问、应用、Provider、Consumer 日志和时区 | 日志查询只读 不写 | request ID + business key + host/index + timeline | 时间统一到绝对时区;无权限时记录缺失证据,不猜日志内容 |
| 环境对比 | 本地正常预发失败 | config names、route、consumer/version | application/config/env.php、application/config/SaasApis.php | 代码版本、配置键、进程、数据和外部合同 | 对比只读;修复按所属系统 old config/process -> intended | commit/version + config key names + health result | 不记录配置值;业务补偿先证明代码/配置修复已生效 |