在 Kubernetes (k8s) 集群中部署 Spring Cloud 微服务时,实现新版本平滑替换的关键在于确保零停机部署(zero-downtime deployment)。Kubernetes 提供了多种策略来实现这一点。以下是一些常用的方法:
滚动更新(Rolling Update):
maxUnavailable 和 maxSurge 参数来控制更新过程中可用和额外 Pods 的数量。蓝绿部署(Blue-Green Deployment):
金丝雀发布(Canary Release):
使用 Readiness Probes:
readinessProbe,Kubernetes 会定期检查容器是否准备好接收流量。readinessProbe 检查通过时,服务才会开始向 Pod 发送流量。使用 Liveness Probes:
livenessProbe 以确定容器何时需要重启。如果检查失败,Kubernetes 将重启该容器,以保持服务的稳定性。设置 Pod Disruption Budget (PDB):
优雅关闭 (Graceful Shutdown):
实际操作中,以下是一些步骤示例:
更新 Deployment 配置:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: your-service
- spec:
- replicas: 3
- strategy:
- type: RollingUpdate
- rollingUpdate:
- maxUnavailable: 1
- maxSurge: 1
- ...
配置 readinessProbe 和 livenessProbe 检查:
- spec:
- containers:
- - name: your-service-container
- image: your-service:new-version
- readinessProbe:
- httpGet:
- path: /actuator/health
- port: 8080
- initialDelaySeconds: 10
- periodSeconds: 5
- livenessProbe:
- httpGet:
- path: /actuator/health
- port: 8080
- initialDelaySeconds: 30
- periodSeconds: 10
当你通过 CI/CD 管道或手动方式更新 Kubernetes Deployment 的配置时,上述设定将启动零停机部署的流程。
为了确保服务间的调用不会在更新过程中失败,你可能还需要考虑实现客户端重试机制和断路器模式,这些可以通过 Spring Cloud 的组件如 Spring Retry 和 Resilience4j
在 Spring Boot 应用中实现优雅关闭(Graceful Shutdown),可以确保应用在停止之前有机会处理完当前正在执行的任务。这个过程通常包括以下几个步骤:
1、配置 Spring Boot 应用的优雅关闭: Spring Boot 2.3 及更新版本提供了直接的支持来配置优雅关闭。在 application.properties 或 application.yml 文件中设置以下配置项:
- server.shutdown=graceful
- spring.lifecycle.timeout-per-shutdown-phase=30s
或者在 application.properties 中:
- server.shutdown=graceful
- spring.lifecycle.timeout-per-shutdown-phase=30s
这里,server.shutdown 设置为 graceful 意味着应用在停止前会完成当前正在处理的请求。spring.lifecycle.timeout-per-shutdown-phase 定义了每个关闭阶段的超时时间,以便在此期间完成清理工作。
2、使用 Spring Boot Actuator: Spring Boot Actuator 提供了 /actuator/shutdown 端点,可以通过 HTTP 调用来触发应用关闭。默认情况下,这个端点是禁用的,需要手动启用:
management.endpoint.shutdown.enabled=true
然后,可以通过发送 POST 请求到 /actuator/shutdown 来触发优雅关闭。
3、在代码中处理关闭信号: 在必要时,你可以监听应用上下文的关闭事件,来执行自定义的清理逻辑:
- @Component
- public class GracefulShutdownHandler implements ApplicationListener<ContextClosedEvent> {
-
- @Override
- public void onApplicationEvent(ContextClosedEvent event) {
- // 执行清理逻辑,如关闭资源、通知其他服务等
- }
- }
4、配置容器的优雅关闭: 如果 Spring Boot 应用运行在容器环境中(比如 Docker 或 Kubernetes),你还需要确保容器平台本身支持优雅关闭。例如,在 Kubernetes 中,你可以设置 Pod 的 terminationGracePeriodSeconds:
- spec:
- terminationGracePeriodSeconds: 60
- containers:
- - name: your-service-container
- image: your-service:latest
- lifecycle:
- preStop:
- exec:
- command: ["/bin/sh", "-c", "sleep 10"]
这里,terminationGracePeriodSeconds 表明在发送 SIGTERM 信号后,Kubernetes 将等待多长时间来关闭容器。preStop 生命周期钩子可以用来执行关闭前的操作,例如稍微延迟关闭,以确保服务有足够的时间完成请求处理。
通过上述的配置和代码实现,你的 Spring Boot 应用将能够在接收到停止信号时,优雅地完成正在处理的请求,然后再关闭。这样可以最大程度减少服务中断带来的影响。