fix(ci): 增加PG/Redis端口连通性检查,解决容器healthy但映射端口连不上 #615

Merged
auto-approve-bot merged 1 commits from fix/ci-pg-connect-retry into develop 2026-07-19 21:48:09 +08:00
Owner

问题

Validate Code Quality 和 Integration Tests 连续多轮偶发失败,错误为 PostgreSQL connection refused。

根因

docker run -P 随机端口映射后,只检查了容器内部健康状态(pg_isready/redis-cli ping),但从宿主侧通过映射端口访问时可能存在延迟(iptables规则建立、网络命名空间切换等)。容器内部 healthy ≠ 宿主端口已可用。

修复

在 docker healthcheck 通过后,增加一层实际 TCP 连通性验证(python socket connect),确保从 job 侧确实能连上后再往下走。

涉及文件:

  • scripts/ci/run_validate.sh — PG 增加 TCP 连通性检查
  • scripts/ci/run_integration_tests.sh — PG 和 Redis 都增加 TCP 连通性检查
## 问题 Validate Code Quality 和 Integration Tests 连续多轮偶发失败,错误为 PostgreSQL connection refused。 ## 根因 `docker run -P` 随机端口映射后,只检查了容器内部健康状态(`pg_isready`/`redis-cli ping`),但从宿主侧通过映射端口访问时可能存在延迟(iptables规则建立、网络命名空间切换等)。容器内部 healthy ≠ 宿主端口已可用。 ## 修复 在 docker healthcheck 通过后,增加一层实际 TCP 连通性验证(python socket connect),确保从 job 侧确实能连上后再往下走。 涉及文件: - `scripts/ci/run_validate.sh` — PG 增加 TCP 连通性检查 - `scripts/ci/run_integration_tests.sh` — PG 和 Redis 都增加 TCP 连通性检查
xiaoxia added 1 commit 2026-07-19 21:41:18 +08:00
fix(ci): 增加PG/Redis端口连通性检查,解决容器healthy但映射端口连不上的问题
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 19s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m6s
AI Code Review / AI Code Review (pull_request) Successful in 3m10s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 3m3s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 3m37s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m4s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 5m43s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 5m49s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 6m50s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 33s
2846b5231e
- run_validate.sh: PG健康检查后增加TCP连通性确认
- run_integration_tests.sh: PG和Redis都增加TCP连通性确认
- 解决docker端口映射延迟导致alembic迁移/测试连接失败的偶发问题

🚀 预览环境已部署

项目 详情
PR号 #615
预览链接 https://pr-615.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #615 | | 预览链接 | [https://pr-615.preview.xiaoxiajianji.com](https://pr-615.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
Collaborator

📊 审查概览

  • 整体评价:有建议
  • 严重问题数量:0 个
  • 一般建议数量:2 个

需修改的问题(严重)

💡 改进建议(一般)

  1. [scripts/ci/run_integration_tests.sh & run_validate.sh] 代码重复与可维护性

    • 具体内容:用于检查 TCP 连接的 Python 单行代码在两个文件中重复出现了 4 次。建议将其提取为一个 Shell 函数(例如 wait_for_tcp),接收 IP 和端口作为参数。这样可以减少代码冗余,便于统一修改超时时间或检查逻辑。
  2. [scripts/ci/run_integration_tests.sh & run_validate.sh] 超时错误提示

    • 具体内容:当前的实现逻辑是:循环结束后,如果仍未连接成功,直接执行最后一次 python3 -c ... 命令。此时脚本会报错退出,但错误信息是 Python 抛出的 ConnectionRefusedErrorTimeoutError,不够直观。建议在循环结束后增加一个判断,如果循环耗尽仍未连接成功,则显式输出 "Error: Timed out waiting for service..." 并退出,以提高日志的可读性。

良好实践

  • 解决端口映射竞态:在 Docker 容器的健康检查通过后,额外增加了 TCP 连接验证,有效解决了容器内部已就绪但宿主机端口映射尚未生效的竞态条件问题,思路严谨。
  • 资源清理:Python 脚本中使用了 s.close() 确保测试 socket 被正确关闭(尽管脚本随即退出,但这是良好的编码习惯)。
  • 超时设置:使用了 s.settimeout(2) 防止连接请求长时间阻塞,符合 CI 环境对时效性的要求。

🤖 由 AI 代码审查机器人自动生成 | 2026-07-19 21:44:28 | 模型:

### 📊 审查概览 - 整体评价:有建议 - 严重问题数量:0 个 - 一般建议数量:2 个 ### ❌ 需修改的问题(严重) 无 ### 💡 改进建议(一般) 1. **[scripts/ci/run_integration_tests.sh & run_validate.sh] 代码重复与可维护性** - 具体内容:用于检查 TCP 连接的 Python 单行代码在两个文件中重复出现了 4 次。建议将其提取为一个 Shell 函数(例如 `wait_for_tcp`),接收 IP 和端口作为参数。这样可以减少代码冗余,便于统一修改超时时间或检查逻辑。 2. **[scripts/ci/run_integration_tests.sh & run_validate.sh] 超时错误提示** - 具体内容:当前的实现逻辑是:循环结束后,如果仍未连接成功,直接执行最后一次 `python3 -c ...` 命令。此时脚本会报错退出,但错误信息是 Python 抛出的 `ConnectionRefusedError` 或 `TimeoutError`,不够直观。建议在循环结束后增加一个判断,如果循环耗尽仍未连接成功,则显式输出 "Error: Timed out waiting for service..." 并退出,以提高日志的可读性。 ### ✅ 良好实践 - **解决端口映射竞态**:在 Docker 容器的健康检查通过后,额外增加了 TCP 连接验证,有效解决了容器内部已就绪但宿主机端口映射尚未生效的竞态条件问题,思路严谨。 - **资源清理**:Python 脚本中使用了 `s.close()` 确保测试 socket 被正确关闭(尽管脚本随即退出,但这是良好的编码习惯)。 - **超时设置**:使用了 `s.settimeout(2)` 防止连接请求长时间阻塞,符合 CI 环境对时效性的要求。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-19 21:44:28 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
auto-approve-bot approved these changes 2026-07-19 21:47:08 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-07-19 21:47:08 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot merged commit df0b3ab452 into develop 2026-07-19 21:48:09 +08:00
auto-approve-bot deleted branch fix/ci-pg-connect-retry 2026-07-19 21:48:09 +08:00

🗑️ 预览环境已清理

PR #615 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #615 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.