ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

k6 v1.6.1 版本解析:experimental/csv 竞态修复、manifest 版本覆盖修复与工具链升级

k6 v1.6.1 版本解析:experimental/csv 竞态修复、manifest 版本覆盖修复与工具链升级 k6 v1.6.1 版本解析experimental/csv 竞态修复、manifest 版本覆盖修复与工具链升级【免费下载链接】k6A modern load testing tool, using Go and JavaScript项目地址: https://gitcode.com/GitHub_Trending/k6/k6k6 v1.6.1 是一次聚焦稳定性与工程化的补丁发布涵盖两个 Bug 修复experimental/csv 模块初始化期的并行csv.parse竞态、manifest 无法覆盖 k6 版本的依赖登记缺陷与三项维护/安全更新with-browser 镜像显式依赖 chromium、Go 工具链与 Docker 镜像版本升级。读完本文你既能理解这两个 Bug 在 k6 的模块系统与依赖供给机制中的成因也能掌握用k6 deps等命令验证脚本依赖、排查自定义构建行为的实操路径。一、v1.6.1 发布总览根据 v1.6.1 发布说明本次补丁版本包含Bug 修复experimental CSV 模块的竞态条件修复对应上游 PR #5632manifest 中 k6 版本覆盖失效的修复PR #5642维护与安全更新with-browserDocker 镜像显式声明 chromium 依赖PR #5641Go 工具链升级至 1.24.13PR #5646Docker 镜像中使用的 Go 版本升级至 v1.25.7PR #5654需要说明的是本文引用的源码均基于当前仓库 HEAD 的代码结构其中部分实现如 go.mod 中的 Go 版本声明在 v1.6.1 之后可能已再次演进涉及版本数字处以下文说明为准。二、Bug 修复详解2.1 experimental/csv 模块并行csv.parse的竞态条件发布说明给出的修复背景是当多个文件脚本文件在初始化期init context使用含异步代码的方式并行调用csv.parse时存在竞态条件。要理解这个问题先看该模块在仓库中的实现位置 internal/js/modules/k6/experimental/csv/module.go。csv.parse的核心执行路径如下以 module.go 的Parse方法为准校验第一个参数必须是k6/experimental/fs的fs.File实例解析用户传入的 Parser 选项delimiter、skipFirstLine、fromLine、toLine、asObjects见 options 结构体通过buildSharedArrayName对「文件路径 解析选项」的 JSON 序列化结果做 SHA-256推导出确定性的共享数组名buildSharedArrayName。这意味着同一文件、同一选项组合在所有 VU 间天然复用同一个SharedArray不会重复占用内存启动 goroutine 读取整个文件最终调用data模块的NewSharedArrayFrom创建共享数组并通过RegisterCallback回到事件循环 resolve Promise。竞态的根源在第 4 步依赖的data模块实例化环节。RootModule需要持有一个全局唯一的dataModuleInstance来创建共享数组。修复后的写法是惰性的、单例式的NewModuleInstancefunc (rm *RootModule) NewModuleInstance(vu modules.VU) modules.Instance { if rm.dataModuleInstance nil { var ok bool rm.dataModuleInstance, ok data.New().NewModuleInstance(vu).(*data.Data) if !ok { common.Throw(vu.Runtime(), errors.New(failed to create data module instance)) } } return ModuleInstance{vu: vu, RootModule: rm} }即多个脚本文件并行初始化时data模块实例被缓存在RootModule上并保证只实例化一次避免了多 goroutine 并发创建/写入共享状态时相互踩踏——这正是「异步代码并行调用csv.parse」触发竞态的典型修复模式。源码注释module.go#L129-L145也明确解释了设计意图Because we rely on the data module to create the shared array, we need to make sure that the data module is initialized before we can proceed, and that we dont instantiate it multiple times.实战视角该模块的典型用法见仓库示例 examples/experimental/csv-parse.js数据文件为 examples/data.csvimport { open } from k6/experimental/fs import csv from k6/experimental/csv import { scenario } from k6/execution export const options { iterations: 10, } // Open the csv file, and parse it ahead of time. const file await open(data.csv); // The csv.parse function consumes the entire file at once, and returns // the parsed records as a SharedArray object. const csvRecords await csv.parse(file, { delimiter: , }) export default async function() { // Each element is a record from the CSV file, represented as an array // where each element is a field from the CSV record. console.log(csvRecords[scenario.iterationInTest]) }补充两点与修复相关的实现细节csv.parse之外的逐行解析入口是new csv.Parser(file, options)NewParser它强制只能在 init context 中调用运行期调用会直接Throw其Next()返回 Promise 逐行读取asObjects与skipFirstLine/fromLine互斥的校验逻辑集中在 newParserOptionsFrom 与 reader.go 的 NewReaderFrom行号统计使用atomic.Int64currentLine本身是并发安全的。2.2 manifest k6 版本覆盖失效k6 未总是被登记为构建依赖第二个修复针对的是 k6 的扩展/依赖供给机制extensions manifests发布说明指出「k6 was not always added as a build dependency, preventing manifests from overriding the k6 version」即 k6 本体没有总是被加入构建依赖列表导致用户通过 manifest 声明的 k6 版本约束无法生效。理解该机制需要看当前仓库中的依赖解析实现internal/cmd/launcher.go 的 checkBuiltinDependencies在执行脚本前k6 会把当前二进制内置的模块含 k6 自身与各编译进二进制的扩展与脚本声明的依赖约束做比对。修复的关键在于k6必须恒出现在这个映射中——源码中显式构建了builtIn : map[string]string{k6: k6Version}launcher.go#L225再叠加ext.GetAll()提供的各扩展版本。若k6本身缺失于依赖映射manifest 中的k6: constraint就会被跳过二进制不会触发「需要自定义构建」的判断版本覆盖自然失效internal/cmd/launcher.go 的 processUseDirectives解析脚本内的use k6 constraint/with k6/x/ext constraint指令含 shebang#!行写入依赖映射internal/cmd/launcher.go 的 checkVersionConstraint约束满足性判定包括对伪版本pseudo-versionv0.0.0-YYYYMMDDHHMMSS-sha的 commit SHA 前缀比对这一特判依赖解析失败时buildProvisioner 会调用 k6build 服务k6provider按依赖清单拉取/构建满足约束的二进制并以子进程方式接管原命令customBinary.run。也就是说manifest 覆盖 k6 版本依赖一条完整链路依赖映射中登记了k6→ 约束比对失败 → 判定需要自定义构建 → 供给满足版本的二进制。修复点正是保证k6在构建依赖中的确定性登记。验证方式可以直接使用仓库中的k6 deps命令internal/cmd/deps.gok6 deps script.js # 或 JSON 输出 k6 deps --json script.js其人类可读输出会包含三部分Build Dependencies各依赖及约束、Imports、Custom Build Required: yes/nooutputHumanReadable。如果脚本 manifest 声明了 k6 版本约束而当前二进制不满足Custom Build Required应为yes——这正是修复前会被错误判定为no的场景。三、维护与安全更新3.1 with-browser Docker 镜像显式声明 chromium 依赖PR #5641with-browser镜像基于 Playwright 驱动 Chromium 做浏览器测试发布说明将其依赖的 chromium 由「隐式存在」改为「显式依赖」。这一改动降低了基础镜像更新时 chromium 意外缺失导致浏览器测试整体不可用的风险。仓库中浏览器能力的示例脚本位于 examples/browser 目录如 examples/browser/pageon.js 等可直接用于验证该镜像环境。3.2 Go 工具链与 Docker 镜像版本升级PR #5646 将 Go 工具链升级至1.24.13构建链所用的 toolchainPR #5654 将 Docker 镜像中使用的 Go 版本升级至v1.25.7。这两个升级属于常规的工程维护跟随 Go 上游的安全与缺陷修复、保持构建环境可复现。需要区分「工具链版本」编译 k6 时使用的 Go toolchain与「镜像中使用的 Go 版本」两者的作用域差异。以当前仓库为准go.mod 声明go 1.25.0、toolchain go1.25.12说明后续版本在此基础上又进一步演进构建发布包的基础镜像定义可参见 packaging/Dockerfile。四、实践检查清单升级到 v1.6.1或在 CI 中固定该版本后建议按以下步骤验证版本确认k6 version应显示 v1.6.1CSV 模块回归使用 examples/experimental/csv-parse.js 及多文件 import 场景在多个脚本文件的 init context 中并行await csv.parse(...)确认无数据错乱或 init 阶段 panic依赖覆盖回归在含use k6 constraint指令或 manifest 依赖声明的脚本上执行k6 deps --json script.js核对buildDependencies中包含k6条目、且customBuildRequired与实际约束比对结果一致浏览器镜像回归如适用在with-browser镜像中运行 examples/browser 下的脚本确认 chromium 可正常拉起。五、相关源码与文档索引主题路径v1.6.1 发布说明release notes/v1.6.1.md前一版本 v1.6.0 说明对照release notes/v1.6.0.mdcsv 模块实现internal/js/modules/k6/experimental/csv/module.go、reader.gocsv 模块示例与数据examples/experimental/csv-parse.js、examples/data.csv依赖/manifest 解析与构建供给internal/cmd/launcher.go、internal/cmd/deps.go打包与镜像构建packaging/DockerfileGo 模块声明go.mod【免费下载链接】k6A modern load testing tool, using Go and JavaScript项目地址: https://gitcode.com/GitHub_Trending/k6/k6创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表