从零开始的云原生之旅(十一):压测实战:验证弹性伸缩效果 - 实践

news/2025/11/28 22:47:29/文章来源:https://www.cnblogs.com/gccbuaa/p/19284352

从零开始的云原生之旅(十一):压测实战:验证弹性伸缩效果

用 k6 进行专业压测,看着 HPA 在真实负载下自动扩缩容,这才是云原生的魅力!

文章目录


前言

在完成 HPA 配置后,我手动发送了一些请求,看到了 Pod 自动扩缩容。但我知道,这还不够

  • 手动测试无法模拟真实负载
  • 无法持续观察长时间的扩缩容行为
  • 缺少性能指标数据

所以,我需要进行专业的压力测试

这篇文章记录我:

  • ✅ 使用 k6 编写压测脚本
  • ✅ 执行长达 9.5 分钟的负载测试
  • ✅ 观察 HPA 在真实负载下的表现
  • ✅ 分析性能指标和优化配置
  • 详细记录踩过的坑和解决方案

压测结果

  • 100% 请求成功率
  • P95 响应时间 983ms
  • 零失败请求
  • HPA 成功扩缩容

一、为什么要做压测?

1.1 手动测试的局限

之前我是这样测试的:

# 手动发送几个请求
for i in {1..10}; do
curl "$SERVICE_URL/api/v1/workload/cpu?iterations=20000000"
done

问题

  • ❌ 只能测试短时间的行为
  • ❌ 无法模拟真实的并发场景
  • ❌ 缺少性能指标(P50、P95、P99)
  • ❌ 无法持续观察扩缩容过程
  • ❌ 没有成功率、错误率等关键指标

1.2 专业压测的价值

使用 k6 等专业工具后:

✅ 模拟真实负载:30 并发用户,持续 9.5 分钟
✅ 自动收集指标:响应时间、成功率、吞吐量
✅ 完整的测试周期:预热 → 增压 → 高负载 → 降压 → 冷却
✅ 观察完整的扩缩容过程
✅ 发现潜在问题(OOM、探针超时等)
✅ 验证系统稳定性

1.3 压测的目标

我的压测目标:

  1. 验证 HPA 是否正常工作

    • CPU/内存超过阈值时自动扩容
    • 负载降低时自动缩容
    • 扩缩容过程平滑
  2. 验证系统稳定性

    • 高负载下 Pod 不崩溃
    • 探针不误杀 Pod
    • 无 OOMKilled 事件
  3. 收集性能基线

    • 响应时间分布(P50、P95、P99)
    • 吞吐量(RPS)
    • 错误率
  4. 发现潜在问题

    • 资源配置是否合理
    • 探针配置是否需要优化
    • HPA 策略是否需要调整

二、选择压测工具:k6

2.1 为什么选择 k6?

对比常见的压测工具:

工具优点缺点适合场景
k6现代化、易用、详细的指标报告相对较新✅ 我的选择
JMeter功能强大、图形界面笨重、资源消耗大传统企业
ab简单、内置功能简陋快速测试
wrk高性能缺少图形界面极限测试
LocustPython 编写、分布式需要写 Python复杂场景

k6 的优势

  • ✅ 使用 JavaScript 编写(前端开发者友好)
  • ✅ 丰富的内置指标(P50、P95、P99)
  • ✅ 支持复杂的测试场景
  • ✅ 美观的终端输出
  • ✅ 支持自定义指标
  • ✅ 开源且活跃

2.2 k6 安装

Windows (Chocolatey)

choco install k6

macOS (Homebrew)

brew install k6

Linux (Debian/Ubuntu)

sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6

验证安装

k6 version
# k6 v0.48.0

2.3 k6 核心概念

VU (Virtual User): 虚拟用户

1 个 VU = 1 个并发用户
30 VU = 30 个并发用户同时发送请求

迭代 (Iteration): 一次完整的测试场景执行

1 次迭代 = 执行一次 default 函数
包括:发送请求 + 检查响应 + sleep

阶段 (Stage): 测试的不同阶段

Stage 1: 预热(VU 从 0 增加到 5)
Stage 2: 增压(VU 从 5 增加到 30)
Stage 3: 高负载(VU 保持 30)
Stage 4: 降压(VU 从 30 降到 5)

指标 (Metrics): 性能数据

- http_req_duration: HTTP 请求耗时
- http_req_failed: 请求失败率
- http_reqs: 总请求数
- checks: 检查通过率

三、编写 k6 压测脚本

3.1 脚本结构

// 1. 导入模块
import http from 'k6/http';
import { check, sleep } from 'k6';
// 2. 配置
export let options = {
stages: [...],      // 测试阶段
thresholds: {...},  // 性能阈值
};
// 3. 测试场景(每个 VU 重复执行)
export default function () {
// 发送请求
// 检查响应
// 等待(模拟用户思考时间)
}
// 4. 生命周期钩子
export function setup() {
// 测试前执行一次
}
export function teardown() {
// 测试后执行一次
}

3.2 配置测试阶段

我的测试计划(总时长 9.5 分钟)

export let options = {
stages: [
// 阶段 1: 预热(30 秒)
{ duration: '30s', target: 3 },
// 阶段 2: 缓慢增压(1 分钟)
{ duration: '1m', target: 10 },
// 阶段 3: 激增负载(2 分钟)- 触发 HPA 扩容
{ duration: '2m', target: 30 },
// 阶段 4: 保持高负载(3 分钟)- 观察扩容效果
{ duration: '3m', target: 30 },
// 阶段 5: 缓慢降压(2 分钟)
{ duration: '2m', target: 10 },
// 阶段 6: 完全冷却(1 分钟)- 观察缩容
{ duration: '1m', target: 3 },
],
// 性能阈值
thresholds: {
'http_req_duration': ['p(95)<5000'],  // 95% 请求在 5 秒内
'http_req_failed': ['rate<0.2'],      // 错误率低于 20%
},
};

阶段设计思路

VUs30 |          ▄▄▄▄▄▄▄▄▄▄▄▄▄▄     ← 阶段 3-4: 高负载,HPA 扩容|        ▄▄                ▄▄10 |      ▄▄                    ▄▄   ← 阶段 2,5: 中负载|    ▄▄                        ▄▄3 |▄▄▄▄                            ▄▄ ← 阶段 1,6: 预热/冷却0 |_____________________________________0   1   2   3   4   5   6   7   8   9  分钟

3.3 实现测试场景

场景:50% CPU 负载 + 50% 内存负载

export default function () {
// 随机选择负载类型
const testType = Math.random();
if (testType < 0.5) {
// 50% - CPU 密集型负载
testCPUWorkload();
} else {
// 50% - 内存密集型负载
testMemoryWorkload();
}
// 随机等待 2-4 秒(模拟用户思考时间)
sleep(Math.random() * 2 + 2);
}
// CPU 密集型测试
function testCPUWorkload() {
const intensity = Math.floor(Math.random() * 10) + 10;  // 10-20 百万次
const url = `${BASE_URL}/api/v1/workload/cpu?iterations=${intensity * 1000000}`;
const res = http.get(url, { timeout: '30s' });
check(res, {
'CPU test: status is 200': (r) => r.status === 200,
'CPU test: has body': (r) => r.body && r.body.length > 0,
});
}
// 内存密集型测试
function testMemoryWorkload() {
const sizeMB = Math.floor(Math.random() * 20) + 20;  // 20-40 MB
const duration = Math.floor(Math.random() * 1) + 1;  // 1-2 秒
const url = `${BASE_URL}/api/v1/workload/memory?size=${sizeMB}&duration=${duration}`;
const res = http.get(url, { timeout: '30s' });
check(res, {
'Memory test: status is 200': (r) => r.status === 200,
'Memory test: has body': (r) => r.body && r.body.length > 0,
});
}

3.4 完整脚本

完整脚本见 k6-tests/hpa-test.js(已在项目中创建)。

核心特性

  • ✅ 混合负载(CPU + 内存)
  • ✅ 随机参数(模拟真实场景)
  • ✅ 超时处理(30 秒)
  • ✅ 错误处理(JSON parse)
  • ✅ 自定义指标(cpu_requests、memory_requests)
  • ✅ 生命周期钩子(健康检查、总结)

四、优化配置准备压测

4.1 我踩的坑:256Mi 内存不够

第一次压测,所有 Pod 都崩溃了!

$ kubectl get pods
NAME                             READY   STATUS             RESTARTS
cloudnative-api-xxx              0/1     CrashLoopBackOff   4
cloudnative-api-yyy              0/1     CrashLoopBackOff   4
cloudnative-api-zzz              0/1     CrashLoopBackOff   4

查看事件

$ kubectl describe pod cloudnative-api-xxx
Events:Warning  BackOff  restarting failed container api

查看 HPA

$ kubectl get hpa
NAME                   TARGETS           REPLICAS
cloudnative-api-hpa    <unknown>/70%     3

问题分析

  1. k6 发送 30 并发请求
  2. 50% 是内存请求,每个分配 20-40MB
  3. 30 × 50% × 30MB = 450MB
  4. 加上 Go 运行时开销 ≈ 550MB
  5. limits: 256Mi → 严重不足 → OOMKilled!

4.2 优化资源配置

调整前

resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"  # ← 不够!
cpu: "300m"

调整后

resources:
requests:
memory: "128Mi"  # 保持不变(HPA 基准)
cpu: "100m"
limits:
memory: "512Mi"  # ← 翻倍!
cpu: "500m"      # ← 提高到 5 倍

为什么这样调整?

配置原值新值原因
memory limits256Mi512Mi防止高负载时 OOM
cpu limits300m500m更大的突发空间
memory requests128Mi128Mi保持不变(HPA 基准)
cpu requests100m100m保持不变(HPA 基准)

关键点

  • requests 不变 → HPA 触发敏感度不变
  • limits 提高 → 支持更高的突发负载

4.3 优化探针配置

第二个坑:高负载下探针超时,Pod 被误杀

Events:
Warning  Unhealthy  Readiness probe failed:
Get "http://10.244.0.66:8080/ready": dial tcp: connect: connection refused
Warning  BackOff    Back-off restarting failed container

问题分析

应用处理 30 个并发请求 → CPU 100%
↓
就绪探针 3 秒超时
↓
应用忙于处理请求,无法响应探针
↓
连续失败 3 次 → Kubernetes 认为 Pod 不健康
↓
重启 Pod → 正在处理的请求丢失
↓
恶性循环:CrashLoopBackOff

优化方案

# 存活探针(避免误杀)
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15      # 增加初始延迟
periodSeconds: 15            # 降低检查频率
timeoutSeconds: 10           # ⭐ 增加超时时间
failureThreshold: 5          # ⭐ 允许更多失败
# 就绪探针(适应高负载)
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10            # 降低检查频率
timeoutSeconds: 10           # ⭐ 增加超时时间
failureThreshold: 6          # ⭐ 允许更多失败

4.4 为什么这样优化?

对比表

探针参数优化前优化后效果
ReadinesstimeoutSeconds3s10s给应用 7 秒额外时间
failureThreshold36允许失败 60 秒
periodSeconds5s10s降低检查频率
LivenesstimeoutSeconds5s10s避免误杀
failureThreshold35允许失败 75 秒

效果

  • ✅ Pod 不会因为短暂的高负载被误杀
  • ✅ 压测期间 Pod 稳定运行
  • 0 次重启

五、执行压测

5.1 准备监控窗口

强烈建议打开 4 个监控窗口

终端 1 - Minikube Service 隧道(Windows PowerShell):

minikube service cloudnative-api-service --url
# 输出: http://127.0.0.1:53163
# 保持运行,不要关闭

终端 2 - HPA 监控

kubectl get hpa cloudnative-api-hpa -w

终端 3 - Pod 监控

kubectl get pods -l app=cloudnative-api -w

终端 4 - 资源监控(PowerShell):

while ($true) {
Clear-Host
Write-Host "=== $(Get-Date -Format 'HH:mm:ss') ===" -ForegroundColor Cyan
kubectl top pods -l app=cloudnative-api 2>$null
kubectl get hpa cloudnative-api-hpa --no-headers 2>$null
Start-Sleep -Seconds 5
}

5.2 启动压测

在新的终端执行

# 进入项目目录
cd cloudnative-go-journey-plan
# 运行压测
k6 run k6-tests/hpa-test.js

输出示例

         /\      Grafana   /‾‾//\  /  \     |\  __   /  //  \/    \    | |/ /  /   ‾‾\/          \   |   (  |  (‾)  |/ __________ \  |_|\_\  \_____/execution: localscript: k6-tests/hpa-test.jsoutput: -scenarios: (100.00%) 1 scenario, 30 max VUs, 10m0s max duration* default: Up to 30 looping VUs for 9m30s over 6 stages
INFO[0000]  Starting HPA Load Test (Light Version)...
INFO[0000]  Target: http://127.0.0.1:53163
INFO[0000] ✅ Health check passed
INFO[0000] ⏰ Test duration: ~9.5 minutes
INFO[0000]  This is a LIGHT version with reduced load

5.3 实时观察

观察终端 2 - HPA 变化

TIME    TARGETS         REPLICAS
00:00   5%/70%, 15%/80%    2        ← 初始状态
01:00   25%/70%, 30%/80%   2        ← 负载上升(预热)
02:00   55%/70%, 50%/80%   2        ← 接近阈值
03:00   85%/70%, 65%/80%   4        ← ⭐ 扩容:CPU 超标
04:00   75%/70%, 60%/80%   4        ← 负载分散
05:00   65%/70%, 55%/80%   4        ← 趋于稳定
06:00   45%/70%, 40%/80%   4        ← 负载下降(降压)
07:00   20%/70%, 25%/80%   4        ← 等待稳定窗口
...     (5 分钟稳定窗口)
12:00   15%/70%, 20%/80%   3        ← ⭐ 缩容:4 → 3
13:00   10%/70%, 18%/80%   2        ← ⭐ 缩容:3 → 2

观察终端 3 - Pod 变化

TIME    NAME                               STATUS
03:00   cloudnative-api-xxx-aaa            Running  ← 原有
03:00   cloudnative-api-xxx-bbb            Running  ← 原有
03:01   cloudnative-api-xxx-ccc            Pending  ← ⭐ 新建
03:01   cloudnative-api-xxx-ddd            Pending  ← ⭐ 新建
03:02   cloudnative-api-xxx-ccc            Running  ← 就绪
03:02   cloudnative-api-xxx-ddd            Running  ← 就绪
...
12:00   cloudnative-api-xxx-ddd            Terminating  ← ⭐ 缩容
13:00   cloudnative-api-xxx-ccc            Terminating  ← ⭐ 缩容

观察终端 4 - 资源使用

=== 02:00:00 ===
NAME                               CPU(cores)   MEMORY(bytes)
cloudnative-api-xxx-aaa            120m         145Mi
cloudnative-api-xxx-bbb            115m         140Mi
=== 03:00:00 ===  ← 高负载
cloudnative-api-xxx-aaa            185m         180Mi
cloudnative-api-xxx-bbb            180m         175Mi
=== 04:00:00 ===  ← 扩容后
cloudnative-api-xxx-aaa            95m          120Mi
cloudnative-api-xxx-bbb            92m          118Mi
cloudnative-api-xxx-ccc            88m          115Mi
cloudnative-api-xxx-ddd            90m          120Mi

六、压测结果分析

6.1 k6 指标解读

测试完成后,k6 输出完整报告

 █ THRESHOLDShttp_req_duration✓ 'p(95)<5000' p(95)=983.18ms        ← ⭐ 优秀!http_req_failed✓ 'rate<0.2' rate=0.00%              ← ⭐ 完美!█ TOTAL RESULTSchecks_total.......: 6370    11.147425/schecks_succeeded...: 100.00% 6370 out of 6370  ← ⭐ 100% 通过checks_failed......: 0.00%   0 out of 6370✓ CPU test: status is 200✓ CPU test: has body✓ Memory test: status is 200✓ Memory test: has bodyCUSTOMcpu_duration...................: avg=15.434094  min=0.6725   med=14.8267   max=86.8117   p(90)=32.08456  p(95)=36.51136cpu_requests...................: 1619   2.833231/smemory_duration................: avg=961.947939 min=933.8644 med=960.23395 max=1107.1016 p(90)=983.36405 p(95)=992.5427memory_requests................: 1566   2.740482/sHTTPhttp_req_duration..............: avg=480.66ms   min=672.5µs  med=48.86ms   max=1.1s      p(90)=974.02ms  p(95)=983.18ms{ expected_response:true }...: avg=480.66ms   min=672.5µs  med=48.86ms   max=1.1s      p(90)=974.02ms  p(95)=983.18mshttp_req_failed................: 0.00%  0 out of 3186    ← ⭐ 零失败http_reqs......................: 3186   5.575462/sEXECUTIONiteration_duration.............: avg=3.47s      min=2.01s    med=3.46s     max=4.98s     p(90)=4.55s     p(95)=4.77siterations.....................: 3185   5.573712/svus............................: 1      min=1         max=30vus_max........................: 30     min=30        max=30NETWORKdata_received..................: 922 kB 1.6 kB/sdata_sent......................: 354 kB 619 B/s
running (09m31.4s), 00/30 VUs, 3185 complete and 0 interrupted iterations
default ✓ [======================================] 00/30 VUs  9m30s

6.2 性能评估

关键指标评分

指标结果行业标准评分
P95 响应时间983ms< 2000ms⭐⭐⭐⭐⭐ 优秀
P50 响应时间48.86ms< 500ms⭐⭐⭐⭐⭐ 优秀
请求成功率100%> 99%⭐⭐⭐⭐⭐ 完美
请求失败率0%< 1%⭐⭐⭐⭐⭐ 完美
检查通过率100%> 95%⭐⭐⭐⭐⭐ 完美

响应时间分析

HTTP 请求耗时分布:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
最小值:    672.5µs  ← CPU 请求(极快!)
P50:       48.86ms  ← 50% 的请求都很快
平均值:    480.66ms ← 被内存请求拉高
P90:       974.02ms
P95:       983.18ms ← 95% 在 1 秒内
最大值:    1.1s     ← 内存请求(可接受)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

关键发现

  • ✅ 中位数只有 48.86ms → 大部分请求非常快
  • ✅ 平均值 480ms vs 中位数 48ms → 少数内存请求拉高平均值(正常)
  • ✅ P95 = 983ms < 1s → 95% 的请求在 1 秒内完成

CPU vs 内存请求对比

类型请求数平均耗时P95 耗时说明
CPU161915.43ms36.51ms非常快 ✅
内存1566961.95ms992.54ms符合预期(1-2秒持有)✅

6.3 HPA 效果分析

扩容表现

T+0:00   负载开始上升
T+2:30   CPU 达到 85%/70%(超过阈值)
T+2:45   HPA 触发扩容:2 → 4
T+3:00   新 Pod 创建完成
T+3:15   新 Pod 接管流量
T+3:30   CPU 降至 65%/70%(低于阈值)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
扩容延迟: ~45 秒(优秀)

缩容表现

T+6:00   负载下降,CPU 降至 45%/70%
T+6:00   进入稳定窗口(300 秒)
T+11:00  稳定窗口结束,开始缩容:4 → 3
T+12:00  继续缩容:3 → 2
T+12:30  回到 minReplicas
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
缩容延迟: ~6 分钟(符合设计)

HPA 评分

维度评分说明
扩容速度⭐⭐⭐⭐⭐45 秒完成,响应及时
扩容准确性⭐⭐⭐⭐⭐从 2 扩到 4,符合计算公式
缩容平滑性⭐⭐⭐⭐⭐5 分钟稳定窗口,避免抖动
指标准确性⭐⭐⭐⭐⭐TARGETS 实时显示,无 unknown
整体稳定性⭐⭐⭐⭐⭐0 次 Pod 重启,0 次 OOM

6.4 与行业标准对比

指标行业标准我的集群评价
可用性99.9% (SLA)100%✅ 超越
P95 响应时间< 2s983ms✅ 优秀
P99 响应时间< 5s~1.1s✅ 优秀
错误率< 1%0%✅ 完美
HPA 响应速度< 60s45s✅ 优秀
资源利用率60-80%65%✅ 理想

结论达到生产级别的性能标准!


七、问题诊断与优化

7.1 CrashLoopBackOff 问题

完整的问题诊断过程

Step 1: 发现问题

$ kubectl get pods
NAME                             STATUS             RESTARTS
cloudnative-api-d99d4f9c-hj9x5   CrashLoopBackOff   4 (49s ago)

Step 2: 查看事件

$ kubectl describe pod cloudnative-api-d99d4f9c-hj9x5 | grep -A 20 Events
Events:
Warning  Unhealthy  Readiness probe failed: connection refused
Warning  BackOff    Back-off restarting failed container api

Step 3: 查看日志

$ kubectl logs cloudnative-api-d99d4f9c-hj9x5 --previous
2025/11/02 08:24:26 ✅ Redis connected successfully
2025/11/02 08:24:26  Server starting on port 8080...
2025/11/02 08:24:33 [GET] /api/v1/workload/cpu | Status: 200
...

关键发现

  • ✅ 应用启动成功
  • ✅ 正常处理请求
  • ❌ 但被探针误杀了

Step 4: 分析原因

应用处理大量请求 → CPU 100%
↓
就绪探针 3 秒超时 → 无法响应
↓
连续失败 3 次(15 秒)→ 被标记为 Unhealthy
↓
Kubernetes 重启 Pod

Step 5: 解决方案

调整探针配置(见 4.3)。

7.2 内存占用分析

问题:为什么 CPU 负载也会导致内存占用高?

原因分析

k6 测试脚本的设计:

export default function () {
const testType = Math.random();
if (testType < 0.5) {
testCPUWorkload();      // 50% CPU 请求
} else {
testMemoryWorkload();   // 50% 内存请求 ← 这个分配内存!
}
}

内存占用计算

30 并发用户
× 50% 内存请求
× 平均 30MB 分配
= 450MB
加上:
+ Go 运行时: ~50MB
+ HTTP 缓冲区: ~30MB
+ Goroutine 栈: ~20MB
= 总计 ~550MB
如果 limits: 256Mi → OOM!
如果 limits: 512Mi → 正常

验证

$ kubectl top pods -l app=cloudnative-api
NAME                               CPU(cores)   MEMORY(bytes)
cloudnative-api-xxx-aaa            185m         180Mi  ← 正常
cloudnative-api-xxx-bbb            180m         175Mi  ← 正常

7.3 优化历程

第 1 次压测:失败

resources:
limits:
memory: "256Mi"  # 不够
cpu: "300m"
readinessProbe:
timeoutSeconds: 3      # 太短
failureThreshold: 3    # 太少

结果

  • ❌ OOMKilled
  • ❌ CrashLoopBackOff
  • ❌ 压测中断

第 2 次压测:成功

resources:
limits:
memory: "512Mi"  # ✅ 翻倍
cpu: "500m"      # ✅ 提高
readinessProbe:
timeoutSeconds: 10     # ✅ 增加
failureThreshold: 6    # ✅ 增加

结果

  • ✅ 0 次 OOM
  • ✅ 0 次重启
  • ✅ 100% 成功率
  • ✅ 压测顺利完成

八、最佳实践总结

8.1 资源配置建议

基于压测结果的推荐配置

# API 服务(中等负载)
resources:
requests:
cpu: "100m"      # HPA 基准,容易触发扩容
memory: "128Mi"  # HPA 基准
limits:
cpu: "500m"      # 5 倍突发空间
memory: "512Mi"  # 4 倍突发空间
# 如果是高并发场景,可以进一步提高:
resources:
limits:
cpu: "1000m"     # 1 核
memory: "1Gi"    # 1G

配置原则

  1. requests 保守:确保 Pod 容易调度,HPA 容易触发
  2. limits 充足:给突发负载足够的缓冲空间
  3. 比例合理:limits = requests × 4-5(CPU),× 4-8(内存)

8.2 探针配置建议

# 启动探针(快速检测启动)
startupProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 0
periodSeconds: 2       # 快速检测
timeoutSeconds: 2
failureThreshold: 15   # 最多等 30 秒
# 存活探针(避免误杀)
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 15      # 降低频率
timeoutSeconds: 10     # ⭐ 关键:高负载下需要更长时间
failureThreshold: 5    # 允许失败 75 秒
# 就绪探针(适应负载变化)
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 10     # ⭐ 关键:高负载下需要更长时间
failureThreshold: 6    # 允许失败 60 秒

关键原则

  • startupProbe 快(2 秒周期)
  • livenessProbe 慢(15 秒周期)
  • readinessProbe 中等(10 秒周期)
  • 高负载场景增加 timeout 和 failureThreshold

8.3 HPA 配置建议

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: your-api
minReplicas: 2       # 高可用:至少 2 个
maxReplicas: 10      # 根据流量峰值设置
metrics:
# ⭐ 始终配置双指标
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70      # 60-70% 是合理范围
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80      # 70-80%,留更多 buffer
behavior:
# ⭐ 快速扩容
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100                  # 可以翻倍
periodSeconds: 15
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Max             # 选择更激进的策略
# ⭐ 保守缩容
scaleDown:
stabilizationWindowSeconds: 300  # 5 分钟稳定期
policies:
- type: Pods
value: 1                    # 每次只减 1 个
periodSeconds: 60
selectPolicy: Min             # 选择保守策略

8.4 压测策略建议

压测脚本设计

  1. 分阶段测试

    • 预热(30s)→ 增压(1m)→ 高峰(3m)→ 降压(2m)→ 冷却(1m)
  2. 混合负载

    • CPU 密集型 + 内存密集型
    • 模拟真实业务场景
  3. 随机参数

    • 请求参数随机化
    • 模拟不同用户行为
  4. 合理的并发

    • 本地测试:20-30 VU
    • 生产验证:50-100 VU
    • 极限测试:200+ VU

监控要点

  • ✅ HPA 扩缩容过程
  • ✅ Pod 状态变化
  • ✅ 资源使用情况
  • ✅ 错误率和响应时间
  • ✅ 系统日志

九、v0.3 完整总结

9.1 学习成果

通过 v0.3 的开发和压测,我掌握了:

1. 弹性伸缩理论

  • ✅ HPA 工作原理和计算公式
  • ✅ Metrics Server 架构和作用
  • ✅ 资源管理(requests/limits)
  • ✅ Pod QoS 和资源保证

2. HPA 实战配置

  • ✅ 编写 HPA YAML 配置
  • ✅ 配置 CPU 和内存双指标
  • ✅ 调优 behavior 策略
  • ✅ 调试和排查 HPA 问题

3. 性能测试技能

  • ✅ 使用 k6 编写压测脚本
  • ✅ 设计多阶段测试场景
  • ✅ 分析性能指标(P50、P95、P99)
  • ✅ 验证系统稳定性

4. 问题诊断能力

  • ✅ 诊断 OOMKilled 问题
  • ✅ 解决探针超时问题
  • ✅ 分析内存占用原因
  • ✅ 迭代优化配置

9.2 核心配置

Deployment 资源配置

resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"      # 5 倍突发
memory: "512Mi"  # 4 倍突发

HPA 配置

minReplicas: 2
maxReplicas: 10
metrics:
- CPU: 70%
- Memory: 80%
behavior:
- scaleUp: 立即响应(0s 稳定窗口)
- scaleDown: 保守缩容(300s 稳定窗口)

探针配置

readinessProbe:
timeoutSeconds: 10      # 高负载适配
failureThreshold: 6     # 避免误杀
livenessProbe:
timeoutSeconds: 10
failureThreshold: 5

9.3 性能指标

压测结果

指标数值评价
总请求数3186-
成功率100%⭐⭐⭐⭐⭐
失败率0%⭐⭐⭐⭐⭐
P50 响应时间48.86ms⭐⭐⭐⭐⭐
P95 响应时间983ms⭐⭐⭐⭐⭐
P99 响应时间~1.1s⭐⭐⭐⭐⭐
吞吐量5.58 req/s符合预期
HPA 扩容延迟45s⭐⭐⭐⭐⭐
Pod 重启次数0⭐⭐⭐⭐⭐

HPA 行为

初始副本: 2
扩容到: 4(CPU 超过 70%)
扩容延迟: ~45 秒
缩容延迟: ~6 分钟(含 5 分钟稳定窗口)
最终副本: 2(回到 minReplicas)

结语

这篇文章标志着 v0.3 弹性伸缩版的圆满完成!

成就解锁

核心收获

  1. 云原生的真正威力

    • 自动应对流量变化
    • 无需人工干预
    • 提高系统可靠性
  2. 资源管理的重要性

    • requests 是 HPA 的基础
    • limits 保护系统稳定
    • 合理配置是成功的关键
  3. 探针配置的艺术

    • 高负载下需要放宽限制
    • timeout 和 failureThreshold 很重要
    • 避免误杀繁忙的 Pod
  4. 性能测试的价值

    • 发现生产前的问题
    • 验证配置是否合理
    • 建立性能基线

下一步

v0.3 完成后,我已经掌握了 Kubernetes 的核心能力:

后续方向

感谢你跟随我的云原生之旅!


系列文章

项目代码:GitHub - cloudnative-go-journey

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/980156.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI浪潮下的机遇与挑战:从技术突破到就业现实

最近刷到不少AI相关的新闻,感觉整个科技圈都在疯狂内卷。一边是DeepSeek开源模型在数学竞赛中击败谷歌,另一边却是苹果的AI论文翻车导致程序员加班。这种冰火两重天的景象,让我这个学软件的不禁思考:AI到底给我们带…

11.19 jdbc

url:"jdbc:mysql://ip:端口/数据库名称" Connection=DriverMan

用C语言和文本文件实现一个简单的,可保存的通讯录

我们先思考一个通讯录都有那些信息,很明显通讯录记录的是人 人有哪些信息呢 这里我就写5个吧,分别是姓名,年龄,电话,性别,地址 然后我们把他们写成一个结构体,最好定义在头文件里,这样在使用的时候更方便 我们…

Ai元人文:价值的惊险一跃——当AI伦理告别“救火”迈向“共生”

Ai元人文:价值的惊险一跃——当AI伦理告别“救火”迈向“共生” 我们正身处一个巨大的认知裂谷之上。裂谷的一侧,是日新月异、以“数值优化”为圭臬的技术逻辑;另一侧,是古老而复杂、以“意义判断”为内核的人类价…

HarmonyOS 应用开发:深入探索截屏与录屏API的创新实践 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

11.28每日总结

今天主要的课程有人机交互技术和机器学习,人机交互的实验做完了,机器学习的实验跟着课程在做,明天去驾校报名,在剩下的大学时间里把能做的多做些

搞定多数据源 + 统一数据格式!用工厂 / 策略 / 适配器模式解决用户端与管理端协同开发痛点

作为一名后端开发,最近在做会员活动相关的用户端系统时,踩了个典型的协同开发坑:管理端和用户端并行开发,管理端负责配置活动规则,用户端需要根据配置展示活动内容,但测试数据源和生产数据源格式不统一、切换数据…

测试档案

测试1测试文章测试标头测试代码

GPU内存层次结构如何影响计算体验

本文深入探讨GPU内存层次结构对计算性能的影响,涵盖CUDA内存类型、缓存层级以及H100系列的新特性,帮助开发者优化内存访问延迟、最大化内存带宽并降低功耗,实现GPU性能的极致发挥。GPU内存层次结构:隐藏的性能瓶颈…

P13270 【模板】最小表示法

题目背景 原模板题:P1368 工艺。 题目描述 若长度为 \(n\) 的字符串 \(s\) 中可以选择一个位置 \(i\),使得 \(\overline{s_i\cdots s_ns_1\cdots s_{i-1}}=t\),则称 \(s\) 与 \(t\) 循环同构。字符串 \(s\) 的最小表…

P5357 【模板】AC 自动机

题目背景 本题原为“AC 自动机(二次加强版)”。完成本题前可以先完成 AC 自动机(简单版) 和 AC 自动机(简单版 II) 两道题,为 AC 自动机更简单的应用。 题目描述 给你一个文本串 \(S\) 和 \(n\) 个模式串 \(T_{…

分布式Session会话实现优秀的方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Revive Adserver存储型XSS漏洞技术分析

本文详细分析了Revive Adserver广告管理系统中的存储型XSS安全漏洞,涉及inventory-retrieve.php和campaign-edit.php文件,包含漏洞复现步骤、技术原理和修复方案,已分配CVE-2025-52667编号。Revive Adserver存储型X…

2025年终总结

多好的35岁,人生黄金期,全盛时期。 2024年年终总结写道:“2024年是个好年份。今年过得真好,有滋有味。果真人生至味是清欢。2024年第一次享受平静,第一次没有大的目标、计划、挑战。只是静心生活,学习,做事。20…

局域网---局域网传输文件及共享桌面

我想要在局域网内进行文件传输以及共享桌面,可以使用文件快传:https://transfer.52python.cn/软件界面:该软件可以联网使用,可以本地部署使用:打完收工!

P2709 【模板】莫队 / 小B的询问

题目描述 小 B 有一个长为 \(n\) 的整数序列 \(a\),值域为 \([1,k]\)。 他一共有 \(m\) 个询问,每个询问给定一个区间 \([l,r]\),求: \[\sum\limits_{i=1}^k c_i^2 \]其中 \(c_i\) 表示数字 \(i\) 在 \([l,r]\) 中…

并不打算的

光和热发货的干扰星级酒店工业

P1903 【模板】带修莫队 / [国家集训队] 数颜色 / 维护队列

题目描述 墨墨购买了一套 \(N\) 支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:\(Q\ L\ R\) 代表询问你从第 \(L\) 支画笔到第 \(R\) 支画笔中共有几种不同颜色的画笔…

P1883 【模板】三分 / 函数

题目描述 给定 \(n\) 个二次函数 \(f_1(x),f_2(x),\dots,f_n(x)\)(均形如 \(ax^2+bx+c\)),设 \(F(x)=\max\{f_1(x),f_2(x),...,f_n(x)\}\),求 \(F(x)\) 在区间 \([0,1000]\) 上的最小值。 输入格式 输入第一行为正…

CSP2025 T4

Sol 赛时是不是多想想就会了??? 考虑 \(f_{i,j,k}\) 表示前 \(i\) 个位置,干掉了 \(j\) 个人,然后有 \(k\) 个位置已经被钦定了。 如果 \(s_i=1\),令 \(c_i\) 表示忍耐度 \(\le i\) 的人数,那么当前可以选的人数…