Cal.diy 预订流程性能测试指南:基于 Grafana k6 的四阶段压测实战

发布时间:2026/11/5 20:40:35

Cal.diy 预订流程性能测试指南:基于 Grafana k6 的四阶段压测实战 Cal.diy 预订流程性能测试指南基于 Grafana k6 的四阶段压测实战【免费下载链接】cal.diyScheduling infrastructure for absolutely everyone.项目地址: https://gitcode.com/GitHub_Trending/ca/cal.diy本指南以 Cal.diy 仓库中的 性能测试套件文档 为核心系统讲解如何利用 Grafana k6 对 Cal.diy 最关键的预订Booking流程开展 smoke、load、stress、spike 四类压测。读完本文你将掌握测试目录的组织方式、命令行与 Docker 两种运行手段、阈值与负载参数的源码级配置以及在此基础上扩展新压测用例的完整方法。性能测试套件概览守护核心预订链路Cal.diy 是一个开源的日程预订基础设施其预订流程Booking Flow——从用户访问某个可预订页面到提交预订——是最核心、最影响用户体验的链路。为此仓库在 packages/testing/performance 目录下内置了一套基于Grafana k6的专用性能测试套件专门用于测量预订流程在不同负载条件下的表现覆盖从低负载功能验证到每分钟数万请求的高并发场景。测试目录结构packages/testing/performance/ ├── smoke/ # 冒烟测试最小负载验证功能是否正常 ├── load/ # 负载测试模拟预期的正常负载每分钟数千请求 ├── stress/ # 压力测试模拟重负载寻找系统瓶颈点每分钟数万请求 ├── spike/ # 尖峰测试模拟突发流量短时间内激增至每分钟数万请求 ├── utils/ # 共享工具与辅助函数 │ ├── config.js # 全局配置阈值、测试用户、环境变量读取 │ └── helpers.js # 核心场景封装预订页面访问 └── README.md # 官方使用文档本指南的原始依据每个负载档位目录下都对应一份booking.js它们复用utils/中的共享配置与辅助函数仅通过options虚拟用户数、时长、阶段与阈值区分压测强度。这种场景复用、参数分层的组织方式使得新增或调整压测档位非常轻量。前置条件运行这套测试需要满足两个基本条件安装 k6在你的机器上安装 Grafana k6官方支持通过包管理器、二进制或 Docker 镜像安装。准备被测实例本地运行中的 Cal.diy默认指向http://localhost:3000或者一个已部署的 Cal.diy 实例。此外若使用 Docker 脚本方式运行还需要本机安装并启动 Docker。运行测试从单条命令到完整压测设置 BASE_URL所有测试默认针对http://localhost:3000运行。若要压测其他环境通过BASE_URL环境变量指定BASE_URLhttps://your-cal-instance.com k6 run tests/performance/smoke/booking.js注意文档中的命令路径如tests/performance/smoke/booking.js对应的是测试位于仓库根目录tests/下的原始布局。在当前仓库中性能测试实际位于 packages/testing/performance因此直接运行时应使用仓库内实际路径例如k6 run packages/testing/performance/smoke/booking.jsBASE_URL的读取与防护逻辑在 config.js 中实现细节见下文共享配置一节。直接运行各档位测试# 运行预订流程冒烟测试最小负载验证功能 k6 run packages/testing/performance/smoke/booking.js # 运行预订流程负载测试每分钟数千请求 k6 run packages/testing/performance/load/booking.js # 运行预订流程压力测试每分钟数万请求 k6 run packages/testing/performance/stress/booking.js # 运行预订流程尖峰测试突发流量激增至每分钟数万请求 k6 run packages/testing/performance/spike/booking.jsk6 运行结束后会自动输出完整的指标报告包括请求吞吐率、错误率、延迟分位数等若任一阈值被突破k6 会以非零退出码结束便于接入 CI。使用 Docker 脚本运行推荐方式除了直接调用 k6套件还提供了 run-k6-local.sh 脚本它会自动检测操作系统Linux / macOS并配置合适的 Docker 参数免去手动拼接docker run命令的麻烦。前置条件Docker 已安装并启动Cal.diy 在本地运行默认http://localhost:3000。交互式菜单用法从仓库根目录执行./packages/testing/scripts/run-k6-local.sh脚本会显示交互式菜单Select a test: 1) smoke 2) load 3) stress 4) spike 5) all 0) exit命令行直传参数也可以跳过菜单直接通过 CLI 参数指定档位# 运行冒烟测试 ./packages/testing/scripts/run-k6-local.sh smoke # 依次运行 smoke/load/stress/spike 全部档位 ./packages/testing/scripts/run-k6-local.sh all脚本实现要点源码级阅读 run-k6-local.sh 源码可以理解脚本的几项关键行为操作系统适配通过uname -s判断平台。在 Linux 下追加--add-hosthost.docker.internal:host-gateway让容器内能通过host.docker.internal访问宿主机上运行的 Cal.diymacOS 无需额外参数其他系统直接报错退出。镜像可定制默认使用grafana/k6镜像可通过K6_IMAGE环境变量覆盖。目录挂载将本地测试目录挂载到容器内/scripts工作目录挂载源可用MOUNT_LOCAL覆盖默认按脚本所在位置推算。当前仓库中测试根目录为 packages/testing因此运行脚本时建议显式指定MOUNT_LOCALpackages/testing ./packages/testing/scripts/run-k6-local.sh load环境变量透传脚本始终注入BASE_URLDocker 模式下默认http://host.docker.internal:3000并仅在变量存在时透传TOKEN、TEST_USER_FREE、TEST_PASSWORD_FREE、TEST_USER_PRO、TEST_PASSWORD_PRO。健壮性检查若测试目录不存在脚本会在启动容器前报错退出。自定义运行参数BASE_URLhttp://localhost:3000 \ TOKENyour_token_here \ ./packages/testing/scripts/run-k6-local.sh load脚本支持的环境变量BASE_URLTOKENTEST_USER_FREETEST_PASSWORD_FREETEST_USER_PROTEST_PASSWORD_PRO共享配置thresholds、测试用户与工具函数config.js 是整个套件的配置中枢所有档位的测试脚本都从这里导入常量。BASE_URL 与生产域名保护export const BASE_URL __ENV.BASE_URL || http://localhost:3000; if (BASE_URL.includes(cal.com)) { throw new Error(BLOCKED: Do not run against production domain); }这里有两层设计意图默认指向本地http://localhost:3000同时硬性拦截包含cal.com的域名一旦误配到生产域名测试在启动阶段就会抛错终止从机制上杜绝了误压生产环境的可能。模拟思考时间export const SLEEP_DURATION { SHORT: 1, MEDIUM: 3, LONG: 5, };SLEEP_DURATION定义了短1s、中3s、长5s三档思考时间用户阅读页面的停顿用于让请求节奏更接近真实用户行为。阈值体系export const THRESHOLDS { HTTP_ERRORS: [rate0.01], RESPONSE_TIME: { SMOKE: { p95: [p(95)500], p99: [p(99)1000] }, LOAD: { p95: [p(95)1000], p99: [p(99)2000] }, STRESS: { p95: [p(95)2000], p99: [p(99)4000] }, SPIKE: { p95: [p(95)3000], p99: [p(99)6000] }, }, };核心阈值分为两类档位HTTP 错误率p95 延迟p99 延迟阈值严格程度smoke 1% 500ms 1000ms最严格用于捕捉性能回归load 1% 1000ms 2000ms中等针对正常运营条件stress 1% 2000ms 4000ms较宽松针对重负载spike 1% 3000ms 6000ms最宽松针对突发流量rate0.01表示请求失败率http_req_failed须低于 1%延迟阈值随负载强度逐级放宽反映负载越高、容忍度越大的测试哲学。测试账号池export const TEST_USERS new SharedArray(users, () [ { username: __ENV.TEST_USER_FREE || free, password: __ENV.TEST_PASSWORD_FREE || free }, { username: __ENV.TEST_USER_PRO || pro, password: __ENV.TEST_PASSWORD_PRO || pro }, ]); export function getRandomUser() { return TEST_USERS[Math.floor(Math.random() * TEST_USERS.length)]; }测试账号池同时包含免费版默认free/free与 Pro 版默认pro/pro两组账号通过SharedArray在所有虚拟用户VU间共享并用getRandomUser()随机抽取模拟不同套餐用户的混合流量。防缓存与随机等待export function randomQueryParam() { return nocache${Date.now()}; } export function randomSleep(min SLEEP_DURATION.SHORT, max SLEEP_DURATION.MEDIUM) { if (min max) { throw new Error(min cannot be greater than max); } const sleepTime Math.random() * (max - min) min; sleep(sleepTime); }randomQueryParam()为每个请求追加基于时间戳的nocache参数绕过浏览器/CDN 缓存保证压测打到真实渲染链路randomSleep()在给定区间内随机休眠且内置min max的参数校验。核心场景实现预订页面访问helpers.js 中封装了本套件唯一的用户旅程场景viewBookingPageexport function viewBookingPage(username, eventSlug) { return group(View Booking Page, () { const url ${BASE_URL}/${username}/${eventSlug}?${randomQueryParam()}; const response http.get(url, { tags: { name: Booking Page }, timeout: 30s, }); check(response, { Booking page loaded: (r) r.status 200, Has booking form: (r) r.body.includes(data-testidday) || r.body.includes(booking), Response time acceptable: (r) r.timings.duration 5000, }); randomSleep(); return response; }); }逐行解读其设计URL 构造${BASE_URL}/${username}/${eventSlug}对应 Cal.diy 的公开预订页路由如/pro/30min并拼接randomQueryParam()防止缓存。请求参数timeout: 30s给出宽松的请求超时tags: { name: Booking Page }将指标聚合到统一的标签名下便于跨档位对比。三重断言status 200验证页面可访问data-testidday验证预订表单日期选择器确实渲染data-testidday这个测试锚点可以在 DatePicker.tsx 中找到对应实现timings.duration 5000给出单请求的兜底延迟红线。节奏控制请求后调用randomSleep()模拟真实用户浏览页面的停顿避免 VU 变成无停顿的压测机器人。分组统计group(View Booking Page, ...)使 k6 报告按此分组展示指标语义清晰。四种压测档位options 逐档剖析四份booking.js都复用viewBookingPage(pro, 30min)作为主场景即压测 Pro 用户30min事件类型的预订页差异完全体现在options中。smoke固定 VU 固定时长smoke/booking.js 采用最简单直接的配置export const options { vus: 10, duration: 2m, thresholds: { http_req_failed: THRESHOLDS.HTTP_ERRORS, http_req_duration: THRESHOLDS.RESPONSE_TIME.SMOKE.p95, }, };10 个虚拟用户恒定运行 2 分钟配合最严格的 p95 500ms 阈值用作每次改动后的快速回归验证。load阶梯式爬坡到 2,000 VUload/booking.js 使用stages定义五段负载曲线阶段时长VU 目标说明12m500爬坡到 500 VU23m1000继续爬坡到 1,000 VU35m2000爬坡到 2,000 VU410m2000维持 2,000 VU 运行 10 分钟53m0缓慢归零主循环sleep(0.1)保持较高请求密度总测试约 23 分钟用于评估正常运营高峰每分钟数千请求下的稳定性。stress逼近并寻找瓶颈点stress/booking.js 的负载曲线更长、更狠阶段时长VU 目标说明12m1000爬坡到 1,000 VU23m2000爬坡到 2,000 VU35m3000爬坡到 3,000 VU410m3000维持 3,000 VU55m4000继续爬坡到 4,000 VU610m4000维持 4,000 VU数万请求/分钟73m0缓慢归零主循环压缩到sleep(0.05)以每分钟数万请求的强度冲击系统寻找吞吐与延迟的拐点。总时长约 38 分钟建议在专门的压测环境执行。spike模拟突发流量尖峰spike/booking.js 模拟流量突变场景阶段时长VU 目标说明11m500基线负载22m50002 分钟内快速激增到 5,000 VU35m5000维持峰值 5,000 VU42m500回落至基线51m0归零总时长约 11 分钟。这类场景适合验证营销活动上线、热点事件等瞬时流量洪峰下系统的弹性与自动扩容表现阈值也是最宽松的p95 3000ms。环境变量参考变量作用默认值BASE_URL被测应用的基础 URLhttp://localhost:3000Docker 脚本模式为http://host.docker.internal:3000TEST_USER_FREE免费版测试账号用户名freeTEST_PASSWORD_FREE免费版测试账号密码freeTEST_USER_PROPro 版测试账号用户名proTEST_PASSWORD_PROPro 版测试账号密码proTOKEN透传给 k6 的令牌脚本模式无K6_IMAGEDocker 模式使用的 k6 镜像脚本模式grafana/k6MOUNT_LOCALDocker 模式挂载的本地测试目录脚本模式脚本位置推算出的默认目录新增测试的最佳实践README 给出了新增用例的标准流程结合源码可以进一步细化创建测试文件在smoke/、load/、stress/或spike/目录下新建 JS 文件如packages/testing/performance/load/booking-create.js。导入共享能力从 utils/helpers.js 导入既有场景封装或参考其模式用group/check编写新场景从 utils/config.js 导入BASE_URL、THRESHOLDS、randomSleep、getRandomUser等能力保证新用例与既有档位共享相同的阈值与账号管理逻辑。定义 options声明 VUs /stages、运行时长与thresholds——务必从THRESHOLDS中按档位选取对应的 p95/p99 阈值而非硬编码数值以便全局统一调整。实现主函数在default函数中编排场景调用并用sleep/randomSleep控制请求节奏。验证运行先用小 VU 数冒烟验证脚本本身无错误再按档位完整执行最后根据结果决定是否纳入 CI 回归。结语把压测沉淀为常态化质量手段Cal.diy 的这套性能测试套件在工程实践上有几个值得借鉴的设计场景与参数分离helpers.js只描述用户旅程options只描述负载与阈值、按档位梯度放宽阈值从 smoke 的 500ms 到 spike 的 3000ms量化了不同负载下可接受的体验水位、以及生产域防护从根上杜绝误压。将 smoke 档位接入每次 CI 回归、将 load/stress/spike 按发布节奏定期执行就能持续量化预订流程的容量水位在流量洪峰到来之前提前发现瓶颈。延伸阅读测试目录的官方说明见 packages/testing/performance/README.md共享配置与场景封装见 config.js 与 helpers.jsDocker 运行脚本见 run-k6-local.sh预订表单的测试锚点实现见 DatePicker.tsx。【免费下载链接】cal.diyScheduling infrastructure for absolutely everyone.项目地址: https://gitcode.com/GitHub_Trending/ca/cal.diy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/1 18:03:18

Midscene.js实战指南:用视觉AI写出E2E测试

Midscene.js实战指南:用视觉AI写出E2E测试 【免费下载链接】midscene GUI Agent for E2E Testing 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene Midscene.js 是一个面向 E2E 测试的 GUI Agent,你用自然语言写指令,AI …

2026/11/1 14:34:25

3步保存微信聊天记录:WeChatMsg(留痕)完整指南

3步保存微信聊天记录:WeChatMsg(留痕)完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Tr…

2026/11/5 16:51:33

EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析

1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被…

2026/11/5 16:26:13

Rust原来很简单二:所有权系统

Part 2 核心篇 —— 所有权系统 本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理 6…

2026/11/5 15:00:49

基于Hadoop+Spark的民宿智能推荐系统设计与实现

1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享…

2026/11/5 14:10:30

ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 14:10:30

UART接口24位ADC搭配RS485,解决远距离温度监控难题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 14:10:30

UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑