性能测试测试后端开发者工具【免费下载链接】FrameworkBenchmarksSource for the TechEmpower Framework Benchmarks project项目地址https://gitcode.com/gh_mirrors/fr/FrameworkBenchmarks点击查看免费下载Voovan 是 TechEmpower Framework BenchmarksTFB中 Java 平台分类下的一款 Web 框架测试实现其相关说明文档位于 frameworks/Java/voovan/README.md。本文以该文档为主线结合仓库内的基准测试配置、Java 源码、构建脚本与工具集实现完整讲解 Voovan 在 TFB 中的接入方式包括/json与/plaintext两个测试接口的 URL 约定、服务端路由的源码实现、运行时 JVM 参数与框架配置文件的调优要点以及 TFB 工具集如何校验与压测这些接口。读完本文你将能够理解并复现一个 Java Web 框架接入 TFB 基准测试的完整链路并掌握 Voovan 服务端在性能测试场景下的关键配置项。Voovan 在 FrameworkBenchmarks 中的定位TechEmpower Framework Benchmarks 是一个用于横向比较各类 Web 开发平台性能的开源项目项目源码位于本仓库根目录。Voovan 以 Java 平台成员的身份参与其中其测试入口定义在 benchmark_config.json 中{ framework: voovan, tests: [{ default: { json_url: /json, plaintext_url: /plaintext, port: 8080, approach: Realistic, classification: Platform, database: None, framework: voovan, language: Java, flavor: None, orm: None, platform: Voovan, webserver: None, os: Linux, database_os: Linux, display_name: voovan-mvc, notes: voovan webserver with mvc } }] }该配置说明了 Voovan 测试的三项关键事实测试类型仅参与 JSON 编码与 Plaintext 编码两类无数据库测试database与orm均为None网络端口固定监听8080端口这也是整个仓库绝大多数框架测试的默认端口约定定位分类approach为Realistic真实场景、classification为Platform平台级、webserver为NoneVoovan 自带 WebServer不依赖外部服务器display_name标注为voovan-mvc即Voovan WebServer MVC的组合。与此对应config.toml 以 TOML 形式记录了同一份元信息供工具集内部解析使用两处文件的字段一一对应。版本差异说明原 README 记录的版本为Java OpenJDK 1.8与Voovan 4.2.x。不过以当前仓库实际内容为准构建阶段基于maven:3-eclipse-temurin-24-alpine镜像运行阶段基于amazoncorretto:25镜像而 pom.xml 中声明的 Voovan 框架版本为4.3.8maven.compiler.source/target均为17。这意味着该测试实现实际面向的是较新的 JDK 与 Voovan 版本README 中的版本描述属于历史记录阅读时应以仓库源码为准。测试 URL 约定Voovan 参与的两项测试 URL 定义在 README 中原文记录如下JSON Encoding Testhttp://localhost:8080/jsonPlaintext Encoding Testhttp://localhost:8080/plaintext这两个 URL 与benchmark_config.json中的json_url、plaintext_url字段严格对应。工具集在验证阶段会以http://{server_host}:{port}{url}的形式拼接请求地址见 framework_test.py因此端口 8080 与路由路径必须与配置保持完全一致否则验证将直接失败。服务端源码实现解析Voovan 测试服务的全部业务逻辑集中在单个入口类 VoovanTFB.java 中主类结构清晰先构建并调优WebServerConfig再注册两条路由最后启动服务。WebServer 配置调优TReflect.register(Message.class); WebServerConfig webServerConfig WebContext.buildWebServerConfig(); webServerConfig.setGzip(false); webServerConfig.setAccessLog(false); webServerConfig.setKeepAliveTimeout(1000); webServerConfig.setHost(0.0.0.0); webServerConfig.setPort(8080); webServerConfig.setHotSwapInterval(0); webServerConfig.setCache(true); webServerConfig.getModuleConfigs().clear(); webServerConfig.getRouterConfigs().clear(); webServerConfig.setEnablePathVariables(false); webServerConfig.setEnableWebSocket(false); WebServer webServer WebServer.newInstance(webServerConfig);这些配置项对基准测试性能有直接影响逐项说明setGzip(false)关闭 Gzip 压缩。基准测试响应体极小压缩反而引入 CPU 开销与响应头变化setAccessLog(false)关闭访问日志避免高并发下的磁盘 I/O 与锁竞争setKeepAliveTimeout(1000)Keep-Alive 超时设为 1000 毫秒配合 wrk 压测脚本的 keep-alive 连接策略setHost(0.0.0.0)/setPort(8080)监听所有网卡接口的 8080 端口保证容器内服务可被外部压测客户端访问setHotSwapInterval(0)关闭热部署扫描间隔避免运行期的文件监听开销setCache(true)开启框架缓存getModuleConfigs().clear()/getRouterConfigs().clear()清空默认模块与默认路由从源码结构看这是为了剔除 Voovan 框架自带的路由分发与模块处理逻辑让服务仅保留基准测试所需的最小处理链路setEnablePathVariables(false)/setEnableWebSocket(false)关闭路径变量解析与 WebSocket 支持进一步削减每请求的处理开销。WebContext.buildWebServerConfig()会读取 config/framework.properties 作为基础配置上述代码再在内存中覆盖关键项。路由注册与响应实现// 性能测试请求; webServer.get(/plaintext, new HttpRouter() { public void process(HttpRequest req, HttpResponse resp) throws Exception { resp.header().put(HttpStatic.CONTENT_TYPE_STRING, HttpStatic.TEXT_PLAIN_STRING); resp.write(HELLO_WORLD_BYTES); } }); // 性能测试请求 webServer.get(/json, new HttpRouter() { public void process(HttpRequest req, HttpResponse resp) throws Exception { resp.header().put(HttpStatic.CONTENT_TYPE_STRING, HttpStatic.APPLICATION_JSON_STRING); resp.write(TString.toAsciiBytes(JSON.toJSON(new Message(HELLO_WORLD_STR), false, false))); } });Plaintext 接口设置Content-Type: text/plain响应头后直接写出预编译的字节数组HELLO_WORLD_BYTESHello, World!.getBytes()。将字符串预编码为字节数组、每次请求复用同一份数组避免重复的编码操作这是 Web 框架 benchmark 中常见的优化手段。JSON 接口设置Content-Type: application/json后构造一个Message对象并调用 Voovan 的 JSON 工具类序列化JSON.toJSON(new Message(HELLO_WORLD_STR), false, false)Message是一个包含message私有字段与getMessage()取值方法的 POJOpublic static class Message { private final String message; public Message(String message) { this.message message; } public String getMessage() { return message; } public int hashCode(){ return 98821452; } }注意main方法开头调用了TReflect.register(Message.class)从源码结构看这是向 Voovan 的反射工具注册该类型使 JSON 序列化能够按反射元数据高效处理该 POJO避免重复解析类结构。序列化结果再经TString.toAsciiBytes(...)转为字节数组写出最终响应体为{message:Hello, World!}形式JSON.toJSON的后两个布尔参数分别控制是否格式化与是否转义此处均传false以输出最紧凑的 JSON。服务启动Logger.setEnable(false); webServer.serve();Logger.setEnable(false)关闭框架日志输出与配置中的setAccessLog(false)互为补充随后webServer.serve()阻塞启动服务。整个 main 方法即构成一个可直接java -jar运行的独立服务。框架核心配置文件详解config/framework.properties 是 Voovan 框架的全局配置由WebContext.buildWebServerConfig()加载。该文件内每项配置均带有原始注释说明完整整理如下配置项当前值框架默认值说明NoHeapManualReleasetruetrue为true时框架会立即手动释放无堆内存NoHeapReleaseInterval60030无堆对象被回收后每隔该间隔秒释放一次无堆内存ThreadPoolMinSize12每个 CPU 核心对应的线程池最小线程数ThreadPoolMaxSize150每个 CPU 核心对应的线程池最大线程数ThreadPoolStatusInterval01000线程池状态日志输出间隔毫秒0表示关闭ByteBufferChannelMaxSize209715201024*1024*2ByteBufferChannel 最大容量字节当前约为默认值的 10 倍SerializeTypeJDKJDK缓存使用的序列化方式可选JDK或JSONJSONConvertEscapeCharfalsetrue为false时 JSON 中的\f \b \r \n \t等转义字符不做 unicode 转换RemoteClassSource注释掉-远程类源码位置形如127.0.0.1:3001当前未启用其中两个线程池参数取值为1表示每个 CPU 核心仅保留 1 个线程。从注释one cpu cores min/max thread size可以推断Voovan 的线程池按 CPU 核心数伸缩JSONConvertEscapeCharfalse则保证 JSON 响应体保持最小的转义处理、输出最紧凑的字节。该文件在运行时通过-cp ./config置于 classpath 下见下节 Dockerfile 的 CMD因此修改参数后无需重新编译。构建与运行Dockerfile 与 JVM 参数voovan.dockerfile 采用多阶段构建FROM maven:3-eclipse-temurin-24-alpine as maven WORKDIR /voovan COPY pom.xml pom.xml COPY src src COPY config/framework.properties config/framework.properties RUN mvn package -q FROM amazoncorretto:25 WORKDIR /voovan COPY --frommaven /voovan/target/voovan-bench-0.1-jar-with-dependencies.jar app.jar COPY --frommaven /voovan/config/framework.properties config/framework.properties EXPOSE 8080第一阶段在maven:3-eclipse-temurin-24-alpine中执行mvn package -q。这里依赖 pom.xml 中配置的maven-assembly-plugin其jar-with-dependencies描述符会将 Voovan 框架依赖一并打入voovan-bench-0.1-jar-with-dependencies.jar产出可直接运行的 fat jar。第二阶段使用amazoncorretto:25作为运行镜像仅拷贝构建产物与配置文件并声明EXPOSE 8080。容器启动命令CMD是性能调优的核心java -DCheckTimeoutfalse \ -DThreadBufferPoolSize1024 \ -DByteBufferSize4096 \ -DAsyncSendfalse \ -DAsyncRecivefalse \ -DByteBufferAnalysis-1 \ -DServerv \ -server -Xms2g -Xmx2g \ -XX:DoEscapeAnalysis \ -XX:AlwaysPreTouch \ -XX:-RestrictContended \ -XX:UseParallelGC -XX:UseNUMA \ --add-opens java.base/java.langALL-UNNAMED \ --add-opens java.base/java.utilALL-UNNAMED \ --add-opens java.base/java.ioALL-UNNAMED \ --add-opens java.base/java.nioALL-UNNAMED \ --add-opens java.base/sun.nio.chALL-UNNAMED \ --add-opens java.base/java.securityALL-UNNAMED \ --add-opens java.base/java.util.concurrentALL-UNNAMED \ --add-opens java.base/java.netALL-UNNAMED \ -cp ./config:voovan.jar:app.jar org.voovan.VoovanTFB各参数的作用可从命名与上下文合理推断Voovan 框架系统属性-DCheckTimeoutfalse关闭连接超时检查-DThreadBufferPoolSize1024设置线程缓冲池容量-DByteBufferSize4096设置 ByteBuffer 初始大小-DAsyncSendfalse与-DAsyncRecivefalse关闭异步收发原样拼写即AsyncRecive-DByteBufferAnalysis-1关闭缓冲区分析-DServerv指定服务器实现标识JVM 堆与内存-server -Xms2g -Xmx2g将堆最小/最大值固定为 2G避免运行期堆扩容抖动-XX:AlwaysPreTouch在启动阶段即预提交全部堆内存页GC 与并发-XX:UseParallelGC选用吞吐优先的并行回收器-XX:UseNUMA启用 NUMA 感知内存分配-XX:DoEscapeAnalysis开启逃逸分析利于栈上分配-XX:-RestrictContended放宽Contended注解的默认限制模块开放一批--add-opens java.base/...ALL-UNNAMED用于在较新 JDK 上放开 Voovan 框架反射访问java.lang、java.util、java.nio、sun.nio.ch等内部包所需的权限新 JDK 强封装限制下常见做法启动入口-cp ./config:voovan.jar:app.jar org.voovan.VoovanTFB将配置目录与依赖 jar 加入 classpath以org.voovan.VoovanTFB作为主类启动。工具集如何校验这两个接口TFB 工具集对 Voovan 的验证逻辑由 json.py 与 plaintext.py 两个测试类型驱动它们从benchmark_config.json中读取json_url与plaintext_url参数见 abstract_test_type.py。JSON 测试的校验规则json.py的verify方法按顺序执行以Accept: application/json,...头发起请求并读取响应通过basic_body_verification检查响应非空且可被json.loads解析通过verify_helloworld_object校验响应对象——要求包含message键、值不区分大小写地等于hello, world!多余键值对与多余空白字节会给出warn详见 verifications.py通过verify_headers检查必须存在Server、Date、Content-Type头以及Content-Length或Transfer-Encoding头且Content-Type须匹配^application/json(; ?charset(UTF|utf)-8)?$正则同时会间隔 3 秒请求两次校验Date头未被缓存详见 verifications.py。这意味着 Voovan 的/json实现必须在Content-Type中使用application/jsonVoovan 的HttpStatic.APPLICATION_JSON_STRING恰好满足且响应体中不得包含多余字段。Plaintext 测试的校验规则plaintext.py的verify方法则要求响应非空响应体转小写后须包含hello, world!子串返回的额外字节数超过 0 会触发warn提示可能影响性能Content-Type匹配^text/plain(; ?charset(UTF|utf)-8)?$状态码为 200头部要求与 JSON 测试相同。这正是 Voovan 的/plaintext路由直接写出Hello, World!字节数组的原因——响应体被精确控制在最少字节数。压测脚本验证通过后工具集调用 wrk 进行压测JSON 测试使用 concurrency.sh固定Accept头、先 primer 后 warmup、再按 concurrency level 阶梯压测Plaintext 测试使用 pipeline.sh额外加载pipeline.lua以 16 级 HTTP 管线深度压测两者均以Connection: keep-alive请求 Voovan 的 8080 端口。这也解释了源码中setKeepAliveTimeout(1000)与端口 8080 的配置来源。本地手动验证不依赖 TFB 工具集时可以手动复现 Voovan 测试服务的验证过程。构建并启动容器后分别执行# JSON 接口 curl -v http://localhost:8080/json # Plaintext 接口 curl -v http://localhost:8080/plaintextJSON 接口应返回Content-Type: application/json与{message:Hello, World!}响应体Plaintext 接口应返回Content-Type: text/plain与Hello, World!响应体。之后可用 wrk 发起与工具集一致的压测例如wrk -H Host: localhost -H Accept: text/plain,text/html;q0.9,*/*;q0.7 \ -H Connection: keep-alive --latency -d 15 -c 512 -t 16 \ http://localhost:8080/plaintext这也是理解 Voovan 在 TFB 中成绩构成的最直接方式——两个接口响应体极小、无数据库参与、无外部 WebServer 层测得的吞吐与延迟基本反映 Voovan WebServer 与 JVM 本身的数据处理能力。小结Voovan 在 FrameworkBenchmarks 中的实现是一个最小化、可复现的基准测试范本README 定义 URL 约定benchmark_config.json声明测试元数据VoovanTFB.java用约 80 行代码完成配置调优与路由注册framework.properties与 Dockerfile 的 JVM 参数共同决定运行时行为而工具集则以严格的头部/响应体校验保证所有参赛框架在同一规则下被测。理解这条链路即可举一反三地将任意 Java Web 框架接入该基准测试体系。赞分享性能测试测试后端开发者工具【免费下载链接】FrameworkBenchmarksSource for the TechEmpower Framework Benchmarks project项目地址https://gitcode.com/gh_mirrors/fr/FrameworkBenchmarks点击查看免费下载相关推荐Tad.xtadx基准测试框架解析基于 Spring Boot Vert.x PostgreSQL 的 Java Web 性能测试实现Tad.xtadx基准测试框架解析基于 Spring Boot Vert.x PostgreSQL 的 Java Web 性能测试实现 导读 本文性能测试测试后端开发者工具Apache Ignite性能测试指南基于Yardstick框架的基准测试Apache Ignite性能测试指南基于Yardstick框架的基准测试 引言 在分布式系统开发中性能测试是验证系统能力的关键环节。Apache Igni数据库分布式数据库后端Kubernetes 调度器性能测试指南深入 scheduler_perf 基准测试框架Kubernetes 调度器性能测试指南深入 scheduler_perf 基准测试框架 导读 test/integration/scheduler_perf云原生容器编排集群管理微服务上一篇Ladybird浏览器高级构建指南深入构建与调试技巧下一篇如何永久保存微信聊天记录简单三步实现数据主权掌控创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考