第四章:应用层高可用设计
应用层的高可用,说白了就是让业务代码本身具备抗风险能力。我见过太多团队把高可用全压在基础设施上,结果应用一重启就雪崩。今天咱们聊聊三个核心点:无状态设计、健康检查与自动摘除、优雅上下线。
4.1 无状态应用设计原则
无状态,是云原生应用的第一条铁律。什么叫无状态?就是应用实例不保存任何业务数据在本地。每次请求都是独立的,换个实例处理也没问题。
我个人习惯把状态分为三类:
- 会话状态:用户登录信息、购物车数据
- 业务状态:订单处理进度、任务执行状态
- 缓存状态:热点数据、计算结果
这三类状态,都不应该留在应用本地。我在项目中遇到过一个大坑:某团队把用户会话存在本地内存里,结果扩容时新实例没有旧会话,用户全被踢下线。嗯,那个晚上大家都没睡好。
核心原则:应用实例 = 纯计算单元。所有状态都交给中间件:Redis存会话,数据库存业务,分布式缓存存热点。
为什么一定要这么做?你想想看,如果应用有状态,Pod重启后数据就丢了。K8s的自动伸缩、滚动更新全都会出问题。说白了,有状态应用在云原生环境里就是个定时炸弹。
4.2 健康检查与自动摘除
健康检查是PaaS平台的"体检医生"。它分三个层次:
| 检查类型 | 探测内容 | 失败后果 |
|---|---|---|
| 存活检查 | 进程是否活着 | 重启Pod |
| 就绪检查 | 能否处理请求 | 从Service摘除 |
| 启动检查 | 初始化是否完成 | 延迟其他检查 |
这里有个常见误区:很多人只配存活检查,不配就绪检查。结果呢?应用还在加载配置,流量就已经打进来了。我曾经见过一个案例,应用启动要30秒,但存活检查5秒就通过了,流量涌入后直接OOM。
我的建议:启动检查用HTTP接口,返回200才算就绪。存活检查用TCP,简单快速。就绪检查要模拟真实请求,比如查一下数据库连接池是否可用。
代码示例,K8s的健康检查配置:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:1.0
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /health/startup
port: 8080
failureThreshold: 30
periodSeconds: 10
注意看startupProbe的failureThreshold设成了30。为什么?因为应用启动可能很慢,尤其是加载大量数据时。我曾经遇到过启动要3分钟的应用,failureThreshold设小了,Pod一直在重启循环。
4.3 优雅上下线机制
优雅上下线,是应用层的"软着陆"。直接kill Pod会怎么样?正在处理的请求断了,数据库连接没释放,缓存数据没同步。嗯,后果很严重。
优雅下线的标准流程:
- 预停止:通知注册中心,本实例要下线了
- 停止接收新请求:健康检查返回非200
- 处理完存量请求:等待正在处理的请求完成
- 释放资源:关闭数据库连接、消息队列等
- 退出进程:调用exit(0)
这里有个关键点:K8s的preStop钩子。我习惯在preStop里做两件事:
- 调用注册中心的注销接口
- sleep 5秒,给负载均衡器时间同步
避坑指南:我曾经遇到过preStop里sleep时间太短,导致流量还在往旧Pod打。后来我改成sleep 10秒,并且配合readiness检查一起用。记住:preStop + readiness是黄金搭档。
优雅上线的流程类似:
- 启动应用:初始化所有组件
- 通过启动检查:告诉K8s我准备好了
- 延迟注册:等几秒再注册到服务中心
- 开始接收流量:就绪检查返回200
代码示例,Spring Boot的优雅关闭配置:
# application.yml
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
这个配置告诉Spring Boot:收到关闭信号后,先停止接收新请求,然后等待最多30秒让存量请求处理完。如果30秒后还有请求没处理完,就强制关闭。
我个人习惯在应用里加一个/health/shutdown接口,手动触发优雅下线。这样在运维操作时,可以先调用这个接口,确认流量切走后,再操作Pod。你想想看,这比直接删Pod安全多了。
总结一下:无状态是基础,健康检查是保障,优雅上下线是细节。这三者配合好了,应用层的高可用才算真正落地。我见过太多线上事故,都是因为这三个点没做好。嗯,希望你能少踩这些坑。