Tips:文末有思考题
在 Nacos 中,服务实例可能会在某些条件下自动下线(即被标记为不健康,并从可用实例列表中移除)。这种行为通常由以下机制控制:
心跳超时(主要原因)
实例注销
deregisterInstance() 方法,主动注销服务实例。服务端检测异常
网络异常
这些参数主要配置在客户端( application.yml 或代码中)。
nacos.naming.heartbeat.interval
描述:客户端发送心跳的间隔时间。
默认值:5000 毫秒(5秒)。
控制作用:降低心跳间隔可以减少误判实例下线的可能性。
示例配置:nacos:
naming:
heartbeat:
interval: 3000 # 心跳间隔为 3 秒nacos.naming.health-check.retrynacos:
naming:
health-check:
retry: 5 # 尝试重试 5 次nacos.naming.health-check.timeoutnacos:
naming:
health-check:
timeout: 20000 # 超时时间设置为 20 秒这些参数主要配置在 Nacos 服务端( application.properties 文件)。
server.health-check.task.interval
server.health-check.task.interval=3000 # 每 3 秒执行一次健康检查任务server.health-check.timeout-ms
server.health-check.timeout-ms=20000 # 心跳超时设置为 20 秒server.health-check.retry
server.health-check.retry=5 # 允许 5 次重试在服务注册时,通过元数据可以设置一些特定健康检查参数。
元数据设置健康检查(例如 HTTP 探针)
metadata:
check: "http"
check_url: "http://127.0.0.1:8080/health"
timeout: 5000 # 超时时间 5 秒
ephemeral 参数
namingService.registerInstance("service-name", "127.0.0.1", 8080, "DEFAULT", true); // true 表示临时实例服务端与客户端时间一致性
服务端性能
网络抖动
heartbeat.interval 和 health-check.timeout 控制心跳逻辑。server.health-check.timeout-ms 和相关参数执行健康检查任务。在 Kubernetes (K8s) 中,Service 的健康检查主要通过 Liveness Probe、Readiness Probe 和 Startup Probe 来实现。这些探针的配置决定了 Pod 的健康状态,并间接影响 Service 的行为,例如负载均衡和流量分发。
Liveness Probe
Readiness Probe
Startup Probe
健康检查通过以下方式执行,所有探针都支持这些方式:
HTTP GET 请求
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 5TCP Socket
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 10
periodSeconds: 5命令执行(Exec)
0 则为健康。livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5以下参数控制探针行为:
initialDelaySeconds
periodSeconds
timeoutSeconds
successThreshold
failureThreshold
以下是一个完整的探针配置示例:
apiVersion: v1
kind: Pod
metadata:
name: probe-demo
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
startupProbe:
httpGet:
path: /startz
port: 8080
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 60探针频率过高:
periodSeconds 和 timeoutSeconds 平衡性能与可靠性。初始延迟不足:
initialDelaySeconds 设置过短,探针可能误判启动中的容器为不健康。网络不稳定:
failureThreshold。通过探针配置,K8s 提供了灵活的健康检查机制,可以结合实际场景优化探针参数和探测方式,实现稳定可靠的服务状态监控。
在 Kubernetes 中,滚动更新(Rolling Update)是默认的部署策略,用于逐步替换旧版本的 Pod 为新版本的 Pod。关于是否会立即将需要替换的某一个 Pod 从 Endpoints 中删除,这取决于以下机制:
启动阶段:
删除阶段:
默认行为
maxUnavailable 和 maxSurge 参数控制:maxUnavailable:最大允许同时不可用的 Pod 数量。maxSurge:最大允许超出指定 Pod 副本数的新增 Pod 数量。Graceful Termination(优雅终止)
以下配置项会影响滚动更新过程中 Pod 在 Endpoints 中的处理方式:
readinessProbe
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 5Deployment 策略中的 maxUnavailable 和 maxSurge
maxUnavailable:定义最多有多少个 Pod 可以同时不可用。maxSurge:定义最多可以多出多少个新 Pod。strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1TerminationGracePeriodSeconds
spec:
terminationGracePeriodSeconds: 30Service 的 publishNotReadyAddresses 参数
publishNotReadyAddresses:true,即使 Pod 未准备好,仍会暴露在 Endpoints 中。spec:
publishNotReadyAddresses: truemaxUnavailable 和 maxSurge,保证服务有足够可用的 Pod。
调试 Endpoints 的变化:
运行以下命令查看 Service 的 Endpoints:kubectl get endpoints <service-name> -o yaml在 Kubernetes 的滚动更新过程中,旧版本的 Pod 被标记为 Terminating 的时间点和新 Pod 的状态(特别是 Ready 状态)之间的关系,取决于 Deployment 策略 和 参数配置。
滚动更新的逻辑
maxUnavailable:允许的最大不可用 Pod 数量。maxSurge:允许的最大超额新增 Pod 数量。Ready。replicas-maxUnavailable。Terminating,并从 Endpoints 中移除。是否等待新 Pod 就绪(Ready)
Ready 后才开始终止一个旧 Pod。maxUnavailable 参数控制了同时不可用的 Pod 数量,默认为 1。Ready,可能会同时终止旧 Pod 并启动新 Pod。strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 2
maxSurge: 1Terminating 状态,即便新 Pod 尚未完全 Ready。ReadyReady,旧 Pod 的终止可能被延迟。ProgressDeadlineSeconds 参数定义超时时间。spec:
progressDeadlineSeconds: 300 # 5分钟内未完成滚动更新则标记失败TerminationGracePeriodSeconds 参数也会影响滚动更新的节奏:Ready,旧 Pod 也可能延迟退出。spec:
terminationGracePeriodSeconds: 60Ready 再终止旧 PodReady,再终止一个旧 Pod。maxUnavailable>0 或 progressDeadlineSeconds 超时,可能会在新 Pod 未完全 Ready 的情况下终止旧 Pod。TerminationGracePeriodSeconds,可能会让旧 Pod 在新 Pod 已 Ready 的情况下仍保持运行一段时间。查看 Pod 状态
kubectl get pods -wTerminating 状态变化。查看 Deployment 策略
kubectl get deployment <deployment-name> -o yamlrollingUpdate 的配置参数。检查更新进度
kubectl rollout status deployment <deployment-name>通过合理配置参数,可以精确控制滚动更新过程,避免新旧 Pod 的流量切换产生中断问题。
思考:为什么流量打到了不健康的pod上?
