diff --git a/测试环境Jenkins部署指南.md b/测试环境Jenkins部署指南.md index b25b92d..76f651d 100644 --- a/测试环境Jenkins部署指南.md +++ b/测试环境Jenkins部署指南.md @@ -1,159 +1,47 @@ -# 开发/测试环境 Jenkins API 自动部署指南 +# TEST 环境 Jenkins 部署指南 -> 最后核对:2026-08-25 -> -> 只适用于当前开发、测试阶段。生产环境启用后必须重新收紧权限、轮换并移除开发 Token。 +更新日期:2026-09-29。本指南描述唯一 TEST 单机目标;仓库配置已收敛不表示实际服务器已部署。统一架构切换与验收以[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)为准。 -## 1. 使用场景 +## 授权与边界 -本指南用于长时间全量测试或夜间任务。用户在当前对话明确要求“持续修复并部署”“自动部署并测试”或等价表述后,工具可以在本次授权范围内循环执行: +默认只做本地修改与离线检查。实际Jenkins构建发布、Nacos发布、SQL和清理分别落实本轮授权范围;本指南不授予持续部署权限。不得读取或覆盖其他任务维护的真实生产/测试凭据。运行事实与本目标不一致时先核对,不自行改名或删除运行环境。 -`定位失败 → 修改代码 → 本地门禁 → 提交并推送 → API 部署 → 等待终态 → 健康/业务验收 → 继续修复` +## 唯一发布入口 -同一轮任务不需要每次提交或重试都重新询问。以下情况仍必须停下确认: - -- 涉及预发布或生产环境。 -- 需要执行 SQL、初始化数据库、修改真实数据或清理容器/数据。 -- 需要跳过测试、停止他人构建或扩大到未授权服务。 -- 缺少环境凭据,或连续三次遇到同一个外部阻断。 - -## 2. 本机一次性配置 - -Jenkins API 信息固定保存在以下未提交文件: - -`C:/Users/BY-OY/.codex/jenkins-api.env` - -文件格式: - -```dotenv -JENKINS_URL=https://jenkins.example.com -JENKINS_USER=admin -JENKINS_API_TOKEN=replace-with-current-development-token -DEV_GATEWAY_URL=https://dev-api.example.com -TEST_GATEWAY_URL=https://test-api.example.com -``` - -工具直接读取该文件,不把 Token 输出到 commentary、最终回复、命令日志或仓库。使用 API Token 的 Jenkins 请求不需要 CSRF Crumb。 - -连通性检查: - -```bash -curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ - "${JENKINS_URL%/}/api/json?tree=nodeName,mode" -``` - -## 3. Job 对照 - -| 环境 | 后端总控 | Admin | Client | 后端分支 | 下游前缀 | -|---|---|---|---|---|---| -| 开发 | `backend-java-dev` | `admin-web-dev` | `client-web-dev` | `dev` | `baiyue-firstleg-dev-` | -| 测试 | `backend-java` | `admin-web-test` | `client-web-test` | `test` | `baiyue-firstleg-` | - -后端可部署服务: - -`gateway`、`gateway-overseas`、`auth`、`iam`、`firstleg`、`finance`、`order`、`warehouse`、`file`、`print`、`integration-service`、`lastleg-service`、`warehouse-overseas-service`、`event-bridge-service`、`audit-service`。海外安全投影随 `lastleg-service` 部署,不再有独立 Job。 - -正常从总控 Job 发起。只有重跑同一提交的单个失败服务时,才直接触发下游 Job。 - -## 4. API 触发 - -### 4.1 前端 - -```bash -curl -fsS -X POST \ - --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ - -D build.headers -o /dev/null \ - "${JENKINS_URL%/}/job/admin-web-dev/build" -``` - -按目标环境和应用替换 Job 名称。 - -### 4.2 后端 - -开发环境选择两个服务的示例: - -```bash -curl -fsS -X POST \ - --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ - -D build.headers -o /dev/null \ - --data-urlencode 'BUILD_MODE=SELECT' \ - --data-urlencode 'SERVICE_GATEWAY_OVERSEAS=true' \ - --data-urlencode 'SERVICE_LASTLEG=true' \ - --data-urlencode 'ENVIRONMENT=development' \ - --data-urlencode 'DEPLOY=true' \ - --data-urlencode 'SKIP_TESTS=false' \ - --data-urlencode 'EVENT_BRIDGE_REGION=BOTH' \ - --data-urlencode 'DOWNSTREAM_JOB_PREFIX=baiyue-firstleg-dev-' \ - "${JENKINS_URL%/}/job/backend-java-dev/buildWithParameters" -``` - -规则: - -- 日常优先 `AUTO`;明确修复单个或少量服务时使用 `SELECT`。 -- `SELECT` 只把目标 `SERVICE_*` 设为 `true`,其余保持 `false`。 -- `ALL` 只用于用户明确授权的全量部署。 -- 开发环境固定 `ENVIRONMENT=development`;测试固定 `ENVIRONMENT=test`。 -- 开发/测试默认 `DEPLOY=true`、`SKIP_TESTS=false`。 -- 事件桥默认 `BOTH`;单区故障重跑才使用 `CN` 或 `OVERSEAS`。 -- 不在 API 参数中传密码、数据库凭据或服务 Token。 - -## 5. 自动等待终态 - -触发响应的 `Location` 是队列地址: - -```bash -QUEUE_URL="$(awk 'BEGIN{IGNORECASE=1} /^Location:/{gsub("\r",""); print $2}' build.headers)" -curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ - "${QUEUE_URL%/}/api/json?tree=id,why,cancelled,executable[number,url]" -``` - -出现 `executable.url` 后,将其作为 `BUILD_URL`: - -```bash -curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ - "${BUILD_URL%/}/api/json?tree=number,building,result,url,duration,estimatedDuration" -``` - -每 5–10 秒轮询一次。只有 `building=false` 且 `result=SUCCESS` 才成功;进入队列、拿到构建号或 HTTP POST 成功都不算完成。后端总控还必须确认每个下游 Job 都是 `SUCCESS`。 - -失败时读取: - -```bash -curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ - "${BUILD_URL%/}/consoleText" -``` - -删除本次产生的临时 `*.headers` 文件,不提交。 - -## 6. 夜间自动闭环 - -1. 记录目标环境、服务和远端 commit。 -2. 运行直接受影响的本地测试;签名变化必须编译测试源码。 -3. 只提交当前修复文件并推送目标分支。 -4. 用 API 触发对应 Job,保存队列 URL、构建 URL 和构建号。 -5. 等待总控及全部下游进入终态。 -6. 失败时读取第一个有效错误,修改后使用新 commit 再部署。 -7. 网络抖动、镜像拉取等瞬时基础设施错误允许同一提交重试,最多两次。 -8. 部署成功后检查 Gateway `/actuator/health`,再执行本轮真实 API/全量测试。 -9. 全部通过后汇总 commit、构建号、服务结果和验收结果。 - -不要因为某个服务失败就盲目重跑全量;优先修复并只重跑失败服务。部署脚本会在新容器不健康时自动回滚,任务仍视为失败。 - -## 7. 快速故障判断 - -| 现象 | 处理 | +| 对象 | 入口 | |---|---| -| `401` | 检查本机 API Token 和反向代理 `Authorization` 头 | -| `403` | 检查 Job Read/Build 权限;不要关闭 CSRF | -| `400` | 参数名或 Choice 值与当前 Job 不一致 | -| 队列长期等待 | 查询队列 `why`,检查节点、执行器和部署锁 | -| Maven/测试失败 | 修复代码并产生新 commit,不跳过测试 | -| 容器不健康 | 读取 Job 自动采集的容器日志和回滚结果 | -| 镜像被其他任务覆盖 | 核对同服务部署锁和实际运行镜像标签 | -| 总控成功但下游失败 | 整体仍按失败处理,只重跑失败服务 | +| 后端总控 | `backend-java`,仓库 `baiyue-firstleg/Jenkinsfile` | +| 后端单服务 | `baiyue-firstleg-`,`Jenkinsfile.service` | +| 构建/部署节点 | `java-builder` / 同机 `java-test` | +| 环境凭据 | Jenkins Secret File `firstleg-test-env`,真实值不入库 | +| 服务与镜像列表 | [service-map.yml](../baiyue-firstleg/deploy/service-map.yml) | +| Compose | [docker-compose.yml](../baiyue-firstleg/deploy/docker-compose.yml),项目 `firstleg-test` | +| 环境模板 | [.env.test.example](../baiyue-firstleg/deploy/env/.env.test.example) | +| Nacos | [config/nacos/test](../baiyue-firstleg/config/nacos/test/README.md),14个Data ID、一个实际Namespace ID | +| 执行顺序与恢复 | [TEST单机部署执行清单](../baiyue-firstleg/deploy/TEST单机部署执行清单.md) | -## 8. 完成记录 +保留13个服务:gateway、auth、iam、order、firstleg、finance、warehouse、warehouse-overseas-service、lastleg-service、file、print、audit-service、integration-service。Gateway Overseas、两区Event Bridge不在新发布清单。停旧服务必须等统一认证、直接投递、撤销和四端切换验证完成;源码退役不等于获准停止当前服务。 -最终只需记录:环境、Job、服务、分支、commit、Jenkins 构建号、最终结果、健康检查、业务验收及剩余阻断。不得输出 Token、Cookie、Jenkins Credential 或环境文件内容。 +旧开发/生产Job不再匹配当前流水线,不能借环境参数使本版本执行生产部署。已有其他环境应由其独立明确授权任务处理,不在本次TEST发布中操作。 -参考:[Jenkins Remote Access API](https://www.jenkins.io/doc/book/using/remote-access-api/)、[Jenkins CSRF Protection](https://www.jenkins.io/doc/book/security/csrf-protection/)。 +## 参数与门禁 + +总控支持AUTO、SELECT、ALL。AUTO保留失败服务重试与直接依赖识别;架构首次切换使用审核后的完整匹配发布清单,不以AUTO遗漏服务。ENVIRONMENT仅test,下游前缀仅baiyue-firstleg-。DEPLOY默认false;IMAGE_REPOSITORY必须替换为已核镜像仓库,DOCKER_BASE_IMAGE由构建节点可访问的Java17镜像提供。不得将凭据拼入参数、URL或日志。 + +默认执行Maven测试;仅明确选择SKIP_TESTS时跳过执行,仍编译测试源码。总控先统一测试,再向固定commit的单服务任务传递跳过重复执行。发布前还须完成网关路由、部署拓扑、失败回滚和受影响前端合同。离线检查不能证明镜像健康或HTTP闭环。 + +单服务任务在取目标节点执行器前锁定对应服务,目标节点通过同一env文件拉镜像并更新容器。没有HEALTHCHECK、启动失败、不健康、退出或超时均判失败。只有同协议同Schema版本才可显式启用ALLOW_SAME_CONTRACT_ROLLBACK;架构切换保持false,恢复原则见执行清单。 + +## 配置与端侧 + +容器共用firstleg-test-network;同网络Web Nginx使用http://gateway:9000。Gateway宿主机发布仅127.0.0.1,业务服务只内部expose。Auth使用http://auth:9100,不能把Nacos应用名当Docker DNS。宿主机中间件通过host.docker.internal访问,不能使用容器localhost。 + +所有服务使用同一Nacos Namespace ID/Group、Redis DB与会话前缀。Auth独占签名私钥;JWKS和内部会话验证共用Auth。EVENT_OPERATIONS_TOKEN独立于内部业务令牌,留空禁用运维操作。现有文件卷和非桥业务MQ保留,topic/group使用test-前缀。 + +Admin与Client各自Compose项目共接后端网络,发布必须给出CLIENT_WEB_URL/VITE_ADMIN_WEB_ORIGIN;两个PDA保留独立产物及仓绑定。域名、Namespace ID、MQ范围、数据卷和主机容量必须据实际清单核实,不能用模板默认值充当验收。 + +## 发布与验收 + +按执行清单记录镜像、配置、SQL与四端版本,在停写窗口发布完整匹配版本。SQL不由Compose/Jenkins自动运行,初始化脚本仅接受两份显式审核的空库基线并受授权开关保护。禁止整机清空Redis/MQ/文件。 + +启动就绪后先验证统一登录/撤销/隔离/仓绑定、资源查询和文件,再用新造数据验证装柜至尾程、资金指令结果回传及故障恢复。真实API通过后还需页面/PDA验收。未部署、未验证项目必须明确标记;不能以Job成功替代整条业务链完成。 diff --git a/统一认证与服务通信契约.md b/统一认证与服务通信契约.md index bd953b3..e767a58 100644 --- a/统一认证与服务通信契约.md +++ b/统一认证与服务通信契约.md @@ -2,7 +2,7 @@ 更新日期:2026-09-29。本文是已确认目标的唯一主契约;当前仅有测试环境,所有服务同机部署。部署与切换见[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)。 -状态:目标契约已确定,整体迁移尚未完成。统一 Token/JWKS/Redis 会话与八类业务事件直连、结构化 ACK 已进入源码并完成分批本地验证;旧海外网关/事件桥模块、部署配置仍未退役。撤销并发窗口、投递失败治理、协议去区域字段与测试环境联调尚待完成,不得混合发布新旧协议或把本地测试视为环境验收。 +状态:整体迁移尚未完成。统一 Token/JWKS/Redis 会话、八类业务事件直连与结构化 ACK、有限重试及人工原事件重试已进入源码并完成分批本地验证。构建与部署已收敛为单 TEST 的13个服务,两个旧模块已退出清单;旧模块源码批量清理被自动审批拒绝,尚未删除。撤销并发替代链的定向验证已通过,旧安全投影链清理、逐次投递审计与指标、协议去区域字段及测试环境联调仍在推进。不得混合发布新旧协议或把本地测试视为环境验收。 下文路径、响应与时序为改造目标。实际业务服务、客户隔离、仓库类型、作业角色与状态机保持原职责;不能将“同机”解释为合并数据库表或绕过权限。 ### A. 唯一路由与消费端映射 @@ -74,7 +74,9 @@ 源码配置已统一为 `baiyue.event-delivery.connect-timeout-ms=3000`、`read-timeout-ms=15000`、`max-attempts=12`、`base-delay-seconds=5`、`max-delay-seconds=1800`、`jitter=0.1`、`lease-seconds=60`,供四个业务 Relay 使用。事件 Feign 客户端显式应用 EventDeliveryFeignConfiguration,禁止客户端内部自动重试及重定向,最终构建参数不被旧的全局 Feign 超时覆盖;连接与读取超时之和必须小于租约时长。`retry_count` 表示已失败或租约超时的投递次数;普通领取不递增,领取超时任务或恢复超时租约时计入一次,自动预算耗尽后保持 DEAD。实际投递失败从失败时刻计算下一次重试时间;每次领取使用独立租约 ID 和当前时间,最终写入必须匹配该 ID。DEAD 保留原始事件,不能通过定时扫描自行恢复。当前人工重试、逐次审计和指标仍在实施,未达到停桥部署门槛。 -每次尝试记录事件、目标、时间、耗时、结果、错误和下一次重试;按服务/类型提供 pending/DEAD 数量及最老待处理时长。告警接入现有能力,不为本次新增独立监控平台。人工重试采用各生产服务的受保护内部操作与配套运维脚本,不新增公开后台页面:只允许 DEAD 原事件重试,记录操作人/原因,保留 eventId/hash/payload/业务幂等键,禁止修改载荷或伪造新 ID 后重发。精确运维接口及脚本参数随对应服务代码提交冻结并测试,不使用直接改表作为验收方式。 +每次尝试记录事件、目标、时间、耗时、结果、错误和下一次重试;按服务/类型提供 pending/DEAD 数量及最老待处理时长。告警接入现有能力,不为本次新增独立监控平台。人工重试采用各生产服务的受保护内部操作与配套运维脚本,不新增公开后台页面:只允许 DEAD 原事件重试,记录操作人/原因,保留 eventId/hash/payload/业务幂等键,禁止修改载荷或伪造新 ID 后重发。 + +人工重试源码接口已冻结:GET `/internal/{firstleg|lastleg|finance}/event-operations/{entryId}` 查询状态,POST 同路径加 `/retry` 提交 `{requestId,operator,reason,expectedPayloadHash}`。使用独立 `X-Event-Operations-Token`,服务配置 `baiyue.event-delivery.operations-token` 对应 `EVENT_OPERATIONS_TOKEN`;缺失或不足32字节时仅关闭该运维能力,不影响业务启动。请求编号为稳定UUID,锁定本服务原Outbox行,DEAD→PENDING和 `event_delivery_retry_audit` 同事务提交;相同请求参数幂等,不同参数冲突,审计失败回滚状态。脚本 `baiyue-firstleg/scripts/event-outbox-operations.mjs` 只接受显式服务源地址与 `CHONGCHONG_ENV=test`,凭据仅从环境读取,不跟随重定向、不自动重试。不得通过公网Gateway或直接改表验收。 信封保留业务事件类型/版本、客户归属、聚合版本、因果/追踪标识及 payloadHash;删除 sourceRegion/targetRegion 及纯区域部署字段时同步 DTO、Validator、构造调用、SQL 基线和测试。语义事件版本及业务载荷不因去桥而随意改动。本轮不重写旧测试事件,不做旧信封兼容。 @@ -84,6 +86,8 @@ Auth 是唯一签发者;Gateway 负责入口令牌与访问域校验,业务 JWT 不携带角色或权限集合,只保留必要身份、客户/应用/仓绑定与版本声明;授权快照取服务端会话,平台/客户/PDA 访问域仍独立校验。客户端不能从 JWT 或外部伪造头获得绕过服务器权限检查的能力。 +并发撤销以持久版本和权威快照指纹为准,不能只依赖删除Redis:Auth账号变更与签发读取使用行锁,Access会话另存状态指纹,Refresh签发前复核旧指纹;Gateway及common-security在Redis会话检查后调用Auth `/internal/auth/accounts/sessions/validate`。Auth重新核对账号版本及IAM当前授权快照,缺失状态或下游不可用拒绝访问。IAM用单条SELECT读取身份、客户、角色权限、两类仓绑定及subject/tenant版本,避免跨查询混合快照。Gateway采用非阻塞HTTP,校验调用不转发Bearer Token,内部服务令牌保护该端点且不递归调用会话验证。此依赖增加每次请求的权威校验成本,测试环境仍须测可用性与延迟。 + | 触发行为 | 撤销范围与负责链 | 必须验证 | |---|---|---| | 当前会话退出 | Auth 撤销当前会话的 Access/Refresh 能力 | 原 Access 被拒绝,原 Refresh 不能恢复 |