00:00:00
加载中...
解决若依和数据库启动顺序导致服务不正常的问题。
本文最后更新于153 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

一、需要解决的问题

若依 Java 应用依赖 MySQL,MySQL 启动时需要初始化数据库(导入 SQL、建表),这个过程比较慢。如果若依比 MySQL 先启动,会报 Connection refused 导致崩溃重启,陷入恶性循环。

解决方案:给 MySQL 加探针控制流量,给若依加 initContainer 控制启动顺序。


二、MySQL 探针配置

MySQL Deployment 添加了两个探针:

livenessProbe(存活探针)– 检测 MySQL 进程是否存活

livenessProbe:
exec:
  command:
  - /bin/sh
  - -c
  - "mysqladmin ping -h 127.0.0.1"
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
  • mysqladmin ping 检测 MySQL 服务是否响应
  • 30 秒后开始探测,每 10 秒一次,连续 3 次失败则重启 Pod
  • 作用:MySQL 挂了自动重启

readinessProbe(就绪探针)– 检测 MySQL 是否可以正常接收连接

readinessProbe:
exec:
  command:
  - /bin/sh
  - -c
  - "CONNECTED=$(mysql -h 127.0.0.1 -N -e \"SHOW STATUS LIKE 'Threads_connected'\" | awk '{print $2}'); [ \"$CONNECTED\" -lt 400 ]"
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
  • 查询 Threads_connected,连接数小于 400 则视为就绪(对应 my.cnf 中 max_connections=400)
  • 10 秒后开始探测,每 5 秒一次
  • 关键作用:readinessProbe 失败时,K8s 会将该 Pod 从 Service 的 Endpoints 中移除,svc-db 不再转发流量到这个 Pod

三、若依 initContainer 配置

若依 Deployment 添加了 initContainer wait-for-mysql:

initContainers:
- name: wait-for-mysql
image: harbor250.oldboyedu.com/oldboyedu-devops/busybox:1.28
command:
- /bin/sh
- -c
- |
  echo "等待 MySQL 就绪..."
  until nc -z svc-db 3306; do
    echo "MySQL 未就绪,等待中..."
    sleep 3
  done
  echo "MySQL 已就绪,启动若依!"

工作原理:

MySQL Pod 启动
  │
  ├─ 端口 3306 打开
  │ 但 readinessProbe 还没通过
  │ → svc-db 的 Endpoints 为空
  │ → nc -z svc-db 3306 失败(无后端)
  │ → initContainer 继续等待
  │
  ├─ 初始化完成(SQL 导入完毕)
  │
  ├─ readinessProbe 检测通过
  │
  └─ Pod IP 被加入 svc-db 的 Endpoints
        │
        │ nc -z svc-db 3306 成功
        │
        └─ initContainer 退出 → 主容器启动

为什么只检查端口就够了: svc-db 只在 MySQL readinessProbe 通过后才转发流量。nc 能通 = MySQL 已通过 readinessProbe = MySQL 初始化完毕且服务可用。不需要额外用 mysql 客户端验证。

镜像选择: 使用 Harbor 仓库已有的 busybox:1.28(1.15MB),避免从 Docker Hub 拉取被墙的问题。


四、若依探针配置

若依 Deployment 添加了三个探针:

startupProbe(启动探针)– 保护 Java 慢启动不被误杀

startupProbe:
httpGet:
  path: /
  port: 8080
failureThreshold: 30
periodSeconds: 10
  • Java 启动慢,给 30 次 x 10 秒 = 300 秒(5 分钟)启动时间
  • startupProbe 存在时,livenessProbe 在启动期间不会生效
  • 启动成功后 startupProbe 自动停止,livenessProbe 接管

livenessProbe(存活探针)– 运行期保活

livenessProbe:
httpGet:
  path: /
  port: 8080
initialDelaySeconds: 120
periodSeconds: 10
failureThreshold: 3
  • 120 秒后开始探测(留给 startupProbe 充足时间)
  • 连续 3 次失败重启 Pod

readinessProbe(就绪探针)– 就绪后才接收流量

readinessProbe:
httpGet:
  path: /actuator/health
  port: 8080
initialDelaySeconds: 60
periodSeconds: 5
failureThreshold: 3
  • 60 秒后开始探测,每 5 秒一次
  • 检测 /actuator/health 端点(需要若依开启 Spring Boot Actuator)
  • 就绪后 svc-ruoyi 才会转发外部流量进来

前提条件: 若依需要开启 Actuator,在 pom.xml 中添加依赖并暴露 health 端点:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
endpoints:
  web:
    exposure:
      include: health

五、完整启动流程

kubectl apply -f 03-ruoyi-single.yaml
│
├─ MySQL Pod 启动
│ ├─ 执行 /docker-entrypoint-initdb.d/ 下的 SQL 初始化脚本
│ ├─ readinessProbe 通过 → 加入 svc-db Endpoints
│ └─ 就绪,等待连接
│
├─ 若依 Pod 启动
│ ├─ initContainer wait-for-mysql 开始执行
│ ├─ nc -z svc-db 3306 等待 MySQL 就绪
│ ├─ MySQL Endpoints 就绪 → nc 成功 → initContainer 退出
│ ├─ 主容器启动
│ ├─ startupProbe 保护 5 分钟启动期
│ ├─ readinessProbe 检测 /actuator/health → 通过
│ └─ svc-ruoyi 转发外部流量 → 若依可访问
│
└─ 全部就绪
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇