当前位置: 首页 > news >正文

Knative Serving:ABP 应用的 scale-to-zero 与并发模型

Knative Serving:ABP 应用的 scale-to-zero 与并发模型 🚀


📚 目录

  • Knative Serving:ABP 应用的 scale-to-zero 与并发模型 🚀
    • 0. TL;DR 🧾
    • 1) 数据面 & 控制面 🧭
    • 2) 与 ABP(.NET)集成点 🧩
    • 3) 并发模型与扩缩判定 📈
    • 4) 冷启动与预热 ❄️🔥
    • 5) Knative Service 清单(ABP 订单服务)🧪
    • 6) 灰度与按路径路由 )🛣️
    • 7) 观测与告警 🔭
    • 8) 压测方法(k6 / hey)🧪⚙️
    • 9) 发布与回滚剧本 🧯
    • 10) ABP/.NET 落地代码片段(健康探针 / Kestrel / 限流)🧱
    • 11) 默认值与调参备忘 🧠
    • 12) FAQ ❓


0. TL;DR 🧾

  • 选择 KPA(Knative Pod Autoscaler)按 并发/RPS 伸缩,原生支持 scale-to-zero(全局开关)HPA 仅支持 CPU/内存,不支持 归零。
  • Activator0→1突发超过 TBC(Target Burst Capacity,默认 200) 时入链缓冲并触发扩容;queue-proxy 在每个 Pod 前实施 硬并发containerConcurrency)与排队并导出指标(仅当 硬并发>1 才会导出 revision_queue_depth)。
  • 冷启动治理:initial-scale(修订创建预热)+ activation-scale(from-zero 预热)+ scale-down-delay(延迟降容)+ stable-window(默认 60s)组合拳。
  • 路由/灰度:Serving 原生 按修订百分比按路径灰度 交给 Ingress/Gateway(Istio/Kong/Contour…)实现。

1) 数据面 & 控制面 🧭

ClientIngress/GatewayActivatorqueue-proxyABP App (user-container)HTTP/gRPC 请求1直达 Revision Pod2硬并发执法/必要时排队3响应4返回并上报指标5进入 Activator on-path6触发扩容并做缓冲7处理请求8响应9指标10返回;产能稳定后退出路径11alt[服务已就绪且产能足够(EBC-≥0,未触发TBC)][scale-from-zero 或 突发>TBC]ClientIngress/GatewayActivatorqueue-proxyABP App (user-container)

2) 与 ABP(.NET)集成点 🧩

  • 健康探针:区分 /healthz/ready(就绪)与 /healthz/live(存活),建议增加 startupProbe(JIT/预热慢时更稳)。
  • Kestrel/HTTP2 并发Http2.MaxStreamsPerConnection 默认 100;与 containerConcurrency 共同收敛端到端并发,避免线程耗尽。
  • 多租户 & 限流:.NET 8 RateLimiter 做租户/接口层限速/限并,叠加 queue-proxy 形成“双层背压”。

3) 并发模型与扩缩判定 📈

concurrency
rps
低于
高于
接近
queue-proxy 导出的
并发/RPS指标
KPA metric
concurrency or rps?
计算平均在途请求/Pod
计算平均RPS/Pod
处于 stable-window?
(默认60s)
是否超过 panic-threshold?
(默认 ≈ 200% of target)
进入 Panic 快速扩容
继续采样与平滑
与 target 比较
减容(受 scale-down-delay 约束)
加容
保持

关键参数

  • 软目标autoscaling.knative.dev/metric=concurrency|rps + .../target
  • 硬上限spec.template.spec.containerConcurrency(>0 启用排队;=0 不限)。
  • TBCautoscaling.knative.dev/target-burst-capacity 控制 Activator on-path(默认 200;0=仅 from-zero 入链,-1=总在链上)。
  • 惊慌窗口panic-window-percentage × window(默认 10% × 60s ≈ 6s)。

4) 冷启动与预热 ❄️🔥

true
true
true
Scale-to-zero
全局开关
initial-scale
新修订创建时拉起 N 个Pod(一次性)
activation-scale
仅在 from-zero 唤醒时拉起 N 个(一次性)
scale-down-delay
低负载保持一段时间再缩容
stable-window=60s
整段窗口无流量才可能归零

只在 KPA 下可用;切到 HPAclass=hpa.*)后最低副本≥1,无法归零。initial-scaleactivation-scale 的生效时机不同:前者→“修订创建”、后者→“从 0 唤醒”。


5) Knative Service 清单(ABP 订单服务)🧪

目标:软并发 5、硬并发 20、初始 1、上限 50;允许归零;显式 queue-proxy 资源;探针分离并加 startupProbegRPC/h2c 用端口名 h2c(不要用 networking 注解切 h2c)。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:name: abp-ordersannotations:serving.knative.dev/rollout-duration: "5m"  # 时间渐进切换;与自动伸缩无耦合
spec:template:metadata:annotations:# ---- Autoscaling (KPA) ----autoscaling.knative.dev/metric: "concurrency"autoscaling.knative.dev/target: "5"autoscaling.knative.dev/min-scale: "0"autoscaling.knative.dev/max-scale: "50"autoscaling.knative.dev/initial-scale: "1"     # 仅“修订创建”时生效autoscaling.knative.dev/activation-scale: "2"  # 仅“从0唤醒”时生效autoscaling.knative.dev/window: "60s"autoscaling.knative.dev/scale-down-delay: "30s"autoscaling.knative.dev/target-burst-capacity: "200"  # 默认 200# ---- queue-proxy 侧车资源(官方注解键名)----queue.sidecar.serving.knative.dev/cpu-resource-request: "50m"queue.sidecar.serving.knative.dev/cpu-resource-limit: "500m"queue.sidecar.serving.knative.dev/memory-resource-request: "64Mi"queue.sidecar.serving.knative.dev/memory-resource-limit: "256Mi"# 可选:queue.sidecar.serving.knative.dev/ephemeral-storage-resource-{request|limit}spec:containerConcurrency: 20containers:- image: ghcr.io/yourorg/abp-orders:1.2.3# 若为 gRPC/h2c,请把端口名设置为 h2cports:- name: h2ccontainerPort: 8080env:- name: ASPNETCORE_URLSvalue: http://0.0.0.0:8080resources:requests: { cpu: "200m", memory: "256Mi" }limits:   { cpu: "1",    memory: "512Mi" }readinessProbe:httpGet: { path: /healthz/ready, port: 8080 }periodSeconds: 5livenessProbe:httpGet: { path: /healthz/live, port: 8080 }periodSeconds: 10# 更稳的启动探针,避免JIT/预热导致反复重启startupProbe:httpGet: { path: /healthz/live, port: 8080 }failureThreshold: 30periodSeconds: 5

6) 灰度与按路径路由 )🛣️

abp-orders 流量按修订
/api/orders/*
/api/payments/*
stable 90%
canary 10%
Revision v1
Knative Service: abp-orders
Revision v2
Ingress/Gateway
Knative Service: abp-payments
  • 按修订百分比:Serving 原生支持;可加 rollout-duration 做时间渐进。
  • 按路径灰度:在 Ingress/Gateway(如 Istio VirtualService、Kong 路由)实现 path/header 区分,把不同路由打到不同 Service,各自再按修订百分比分流。

7) 观测与告警 🔭

核心指标拓扑:

Data Plane
route
direct
scale-to-zero 或 突发
metrics
p50/p95/p99
Knative Service
Ingress
queue-proxy
Pod 内 sidecar
Activator
Autoscaler/KPA
Prometheus/Grafana
* 注意:revision_queue_depth 仅在 containerConcurrency > 1 时导出

PromQL 示例(使用 container_name 选择 Activator,避免依赖 job 名):

# Activator 在途比例(近 5 分钟)
sum(rate(request_count{container_name="activator", revision_name="abp-orders"}[5m]))
/
sum(rate(revision_request_count{revision_name="abp-orders"}[5m]))# p95(queue-proxy 总时延)
histogram_quantile(0.95,sum by (le, revision_name) (rate(revision_request_latencies_bucket{revision_name="abp-orders"}[5m]))
)# 队列深度(仅当 containerConcurrency>1)
max by (revision_name) (revision_queue_depth{revision_name="abp-orders"})

💡 若启用 Service Mesh mTLS,需按发行版指引允许 Prometheus 抓取 Serving 组件指标(Activator/queue-proxy),否则面板会“空白”。


8) 压测方法(k6 / hey)🧪⚙️

目标场景

  1. 0→突发:空闲 2 分钟后 200 RPS 持续 5 分钟;
  2. 长尾低频:每分钟 3–5 个请求;
  3. 窄峰宽谷:10 分钟峰 + 20–30 分钟低频。

k6(RPS 精确控制)

// k6-burst.js
import http from 'k6/http'; import { sleep } from 'k6';
export const options = {scenarios: {burst_from_zero: { executor: 'constant-arrival-rate', rate: 200, timeUnit: '1s',duration: '5m', preAllocatedVUs: 50, maxVUs: 200 },long_tail: { executor: 'ramping-arrival-rate', startRate: 3, timeUnit: '1m',stages: [{ duration: '20m', target: 5 }] }}
};
export default () => { http.get(`${__ENV.URL}/api/orders/ping`); sleep(1); };

hey(-q 为“每 worker 的 QPS”,总 RPS ≈ q * c

# 约 200 RPS、持续 5 分钟:200 并发 * 1 qps/worker ≈ 200 rps
hey -z 5m -c 200 -q 1 -m GET "${URL}/api/orders/ping"
# 约 400 RPS:-q 2

评测输出建议:绘制 initial-scale=0/1/2 × containerConcurrency=10/20/50p95 / 冷启动命中率 / 成本 三曲线,挑选满足 SLO 的最低成本组合。


9) 发布与回滚剧本 🧯

  • 发布前检查enable-scale-to-zero=truestable-window=60starget-burst-capacity=200
  • 灰度策略:按修订百分比 1%→10%→25%→50%→100%,或用 serving.knative.dev/rollout-duration 做时间型平滑切换。
  • 快速回滚:把 traffic 切回稳定修订;必要时临时 min-scale=1/提升 activation-scale 抑制冷启动,再定位根因。

10) ABP/.NET 落地代码片段(健康探针 / Kestrel / 限流)🧱

健康探针(Program.cs)

using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.Diagnostics.HealthChecks;builder.Services.AddHealthChecks().AddCheck("db", () => HealthCheckResult.Healthy(), tags: new[] { "ready" });var app = builder.Build();app.MapHealthChecks("/healthz/ready",new HealthCheckOptions { Predicate = r => r.Tags.Contains("ready") });
app.MapHealthChecks("/healthz/live",new HealthCheckOptions { Predicate = _ => false });app.Run();

Kestrel/HTTP2 并发

builder.WebHost.ConfigureKestrel(o =>
{o.Limits.MaxConcurrentConnections = 1024;o.Limits.Http2.MaxStreamsPerConnection = 100; // 默认 100,可按需调
});

租户限流(.NET 8 RateLimiter)

using System.Threading.RateLimiting;builder.Services.AddRateLimiter(o =>
{o.AddPolicy("per-tenant", ctx =>RateLimitPartition.GetTokenBucketLimiter(ctx.Request.Headers["X-TenantId"].ToString() ?? "anon",_ => new TokenBucketRateLimiterOptions {TokenLimit = 50, TokensPerPeriod = 50,ReplenishmentPeriod = TimeSpan.FromSeconds(1),QueueLimit = 200, QueueProcessingOrder = QueueProcessingOrder.OldestFirst,AutoReplenishment = true}));
});
var app = builder.Build();
app.UseRateLimiter();

11) 默认值与调参备忘 🧠

  • container-concurrency-target-default = 100
  • requests-per-second-target-default = 200
  • target-burst-capacity = 200
  • stable-window = 60spanic-window-percentage = 10%(惊慌窗口≈6s)
  • activation-scale from-zero 生效;initial-scale 修订创建时生效
  • revision_queue_depth:仅当 containerConcurrency > 1 才会导出

12) FAQ ❓

  • 切到 HPA 为啥不能归零? → HPA 最低副本≥1;只有 KPA 支持 scale-to-zero。
  • containerConcurrency vs target → 前者是 硬上限(触发排队),后者是 软目标(指导扩缩)。
  • Activator 是否影响时延? → 看 Activator request_count/latencies 与服务侧 p95 的联动;必要时调高 activation-scale/TBC
  • revision_queue_depth 没数据? → 设置 containerConcurrency > 1 才会导出该指标。
  • gRPC/h2c 怎么启用? → 将容器端口 命名为 h2c(或配相应 appProtocol);不要用 networking 注解去切 h2c。

文章转载自:

http://bwFHTRs4.Lmxfy.cn
http://wLVs5FXY.Lmxfy.cn
http://0XvGNztM.Lmxfy.cn
http://DGOfyfkW.Lmxfy.cn
http://RCSIX5W7.Lmxfy.cn
http://nvS5MwGV.Lmxfy.cn
http://Kn0QhkrI.Lmxfy.cn
http://mtTpC5Kf.Lmxfy.cn
http://XetaZyPC.Lmxfy.cn
http://Hh3jdG2O.Lmxfy.cn
http://mYRk61uy.Lmxfy.cn
http://rO1q6EMR.Lmxfy.cn
http://QRTUJqJP.Lmxfy.cn
http://iy2B1N7h.Lmxfy.cn
http://eRlc5bWA.Lmxfy.cn
http://BtfpwvcC.Lmxfy.cn
http://vPrMZBSH.Lmxfy.cn
http://NWZKKoCt.Lmxfy.cn
http://RwEuTkLA.Lmxfy.cn
http://O75VSK5G.Lmxfy.cn
http://ji7hBw1m.Lmxfy.cn
http://036US6EG.Lmxfy.cn
http://j7VRQKMb.Lmxfy.cn
http://EwAALe6m.Lmxfy.cn
http://SaMewlUp.Lmxfy.cn
http://TbQbUGHF.Lmxfy.cn
http://3UkA7KTd.Lmxfy.cn
http://L9uyQ7fM.Lmxfy.cn
http://TqFakptJ.Lmxfy.cn
http://1fNdXXS6.Lmxfy.cn
http://www.dtcms.com/a/371227.html

相关文章:

  • Xsens帮助独立工作室创造引人注目的冒险游戏真实角色动画
  • 《动手学深度学习v2》学习笔记 | 2.4 微积分 2.5 自动微分
  • 【开题答辩全过程】以 哈尔滨裕丰草莓园管理系统为例,包含答辩的问题和答案
  • 国内外支持个人开发者的应用市场
  • 【LLIE专题】SIED:看穿0.0001lux的极致黑暗
  • ANSYS HFSS边界条件的认识
  • python系列之综合项目:智能个人任务管理系统
  • IOC为什么交由spring容器管理?
  • spring事务传播机制
  • LeetCode_数学
  • (nice!!!)(LeetCode 面试经典 150 题 ) 130. 被围绕的区域(深度优先搜索dfs || 广度优先搜索bfs)
  • 虚拟化技术
  • 【74页PPT】MES简介(附下载方式)
  • 基于Pygame的六边形战术推演系统深度剖析——从数据结构到3D渲染的完整实现(附完整代码)
  • 强化学习入门:从零开始实现DDQN
  • 开启Python之路,第一节学习大纲-从入门到进阶
  • 单词分析与助记之数据建表(以production为例)
  • 【温室气体数据集】亚洲地区长期空气污染物和温室气体排放数据 REAS
  • 高精度地图
  • 美陆军启用数字仿真与分析中心;首次测试AI空战指挥官“星智“系统;五角大楼计划削减关键技术清单
  • 《秦时明月》系列经典语录分享
  • 《用 Python 构建并发 API 爬虫:从基础到高性能实战》
  • 语义切片技术深度解析:重新定义RAG时代的文本处理范式
  • LeetCode - 1089. 复写零
  • C++ 小游戏:拍桌子
  • 魅族 Note 16 解锁 BL 及 Root 官方刷机包下载Flyme 12.0.1.5A 型号 M521Q
  • AI(学习笔记第七课) 使用langchain进行文本切割
  • Coze平台指南(3):核心功能-创建智能体与设计角色
  • 单例模式(巨通俗易懂)普通单例,懒汉单例的实现和区别,依赖注入......
  • 第五十三天(sql注入)