
性能测试测试后端开发者工具【免费下载链接】FrameworkBenchmarksSource for the TechEmpower Framework Benchmarks project项目地址https://gitcode.com/gh_mirrors/fr/FrameworkBenchmarks点击查看免费下载本指南以 tio-boot 框架的 TechEmpower 基准测试实现 为主体系统讲解该实现如何基于 t-io 网络框架与 tio-boot 应用骨架完成 Plaintext、JSON、数据库查询、多查询、更新、模板渲染与缓存查询七大测试场景并给出 MySQL 8 环境准备、Docker 构建与运行、Windows 本地运行的完整实操方案。读者阅读后既能理解每个测试端点的源码实现思路也能直接在本地或容器中把整个基准测试服务跑起来。项目背景与定位tio-boot 是位于frameworks/Java/tio-boot/目录下的一个 Java Web 基准测试实现其底层网络通信层为t-io一个高性能网络框架业务层采用tio-boot2.0.6与java-db1.5.6应用骨架。在 TechEmpower 基准测试套件中它被归类为approachRealistic真实场景classificationMicro微框架databaseMySQLormRaw原生 SQL / ActiveRecord 直查platformt-iowebserverNone自带 Web 服务器能力不依赖外部 Web 容器以上元数据来自 benchmark_config.json 与 config.toml。也就是说整个服务是一个自包含的 HTTP 服务器监听 8080 端口直接对外提供基准测试要求的各类接口无需 Nginx 等前置网关。测试场景与源码实现README 将全部实现归纳为 Controller 层的七大测试虽然 README 中给出的类名controller/IndexController.java、controller/DbController.java、controller/CacheController.java与当前仓库的实际目录结构略有出入——当前仓库将路由处理器统一放在handler/包下——但功能一一对应。下面结合实际源码逐一展开。Plaintext 纯文本测试对应 PlaintextHandler.java。实现要点是完全静态化响应private static final String HELLO_WORLD Hello, World!; private static final byte[] HELLO_WORLD_BYTES HELLO_WORLD.getBytes(StandardCharsets.UTF_8); Override public HttpResponse handle(HttpRequest httpRequest) throws Exception { HttpResponse response TioRequestContext.getResponse(); response.setBody(HELLO_WORLD_BYTES); String mimeTypeStr MimeTypeUtils.getTextUTF8(); response.setContentType(mimeTypeStr); return response; }响应体在类加载时就被编码为 UTF-8 字节数组并缓存为常量每次请求直接复用同一字节数组避免重复的字符串编码分配同时显式设置text/plain; charsetUTF-8类型。从源码结构看这是以「零分配」为目标的最简路径。JSON 序列化测试对应 JsonHandler.java使用fastjson2pom.xml 中版本 2.0.60序列化private static final byte[] JSON_BYTES JSON.toJSONBytes(new Message(HELLO_WORLD)); Override public HttpResponse handle(HttpRequest httpRequest) throws Exception { HttpResponse response TioRequestContext.getResponse(); response.setBody(JSON_BYTES); String mimeTypeStr MimeTypeUtils.getJsonUTF8(); response.setContentType(mimeTypeStr); return response; }与 Plaintext 相同的思路{message:Hello, World!}的 JSON 字节在启动时一次性序列化并缓存运行时只做响应体赋值。返回的模型类为 Message.java是一个只含message字段的不可变类。代码注释中还保留了用ab -k -n1000000 -c10进行本地压测的参考命令。单条数据库查询DB Test对应 DbHandler.java 的db方法。它通过 java-db 的 ActiveRecord 能力按主键查询world表public HttpResponse db(HttpRequest request) { Integer id request.getInt(id); if (id null) { id RandomUtils.randomWorldNumber(); } HttpResponse httpResponse TioRequestContext.getResponse(); Row recored Db.findById(world, id); if (recored ! null) { httpResponse.setBody(JSON.toJSONBytes(recored.toMap())); } else { httpResponse.setBody(bytes); } httpResponse.addHeader(HeaderName.Content_Type, HeaderValue.Content_Type.TEXT_PLAIN_JSON); return httpResponse; }id的生成逻辑在 RandomUtils.javaThreadLocalRandom.current().nextInt(1, 10001)即 1~10000 的随机主键用ThreadLocalRandom避免多线程下的随机数竞争。多查询测试Queries Testqueries方法解析queries查询参数并循环查库String queries request.getParam(queries); int queryCount RandomUtils.parseQueryCount(queries); int[] randomNumbers RandomUtils.randomWorldNumbers().limit(queryCount).toArray();参数解析规则也在RandomUtils中public static int parseQueryCount(String textValue) { if (textValue null) return 1; int parsedValue; try { parsedValue Integer.parseInt(textValue); } catch (NumberFormatException e) { return 1; } return Math.min(500, Math.max(1, parsedValue)); }即缺省或非法时按 1 处理合法值被钳制在[1, 500]区间。randomWorldNumbers()使用ThreadLocalRandom.current().ints(1, 10001).distinct()生成去重后的随机 id 流——源码注释特别说明使用distinct()是为了避免利用任何一级缓存绕过真实数据库查询确保查询确实打到 MySQL。随后每个 id 依次执行Db.findById(world, id)收集结果并用 fastjson2 输出 JSON 数组。数据库更新测试Updates Testupdates方法遵循 TechEmpower 更新测试的规范流程先读后写并保证新随机数与旧值不同EhCacheKit.removeAll(world); // 先清空缓存确保读到的是最新值 for (int id : randomNumbers) { Row row Db.findById(world, id); if (row ! null) { int currentRandomNumber row.getInt(randomNumber); int newRandomNumber; do { newRandomNumber RandomUtils.randomWorldNumber(); } while (newRandomNumber currentRandomNumber); row.set(randomnumber, newRandomNumber); Db.update(world, id, row); // update updatedRecords.add(row.toMap()); } }值得注意的实现细节方法开头先调用EhCacheKit.removeAll(world)清空world缓存区域随后执行读-改-写最终返回更新后的记录数组 JSON。这一步与缓存查询测试共用同一套 EhCache 基础设施保证了更新操作能反映最新数据。模板渲染测试Fortunes Testfortunes方法使用JFinal Enjoy 模板引擎渲染 HTML 表格完整流程如下ListRow records Db.find(SELECT * FROM fortune); ListFortune fortunes new ArrayList(records.size()); for (Row record : records) { fortunes.add(record.toBean(Fortune.class)); } fortunes.add(new Fortune(0L, Additional fortune added at request time.)); // 附加一条固定数据 fortunes.sort(Comparator.comparing(Fortune::getMessage)); // 按 message 字典序排序 MapString, Object viewData new HashMap(); viewData.put(fortunes, fortunes); String html template.renderToString(viewData); return Resps.html(httpResponse, html);对应的模型是 Fortune.java模板文件为 templates/fortunes.htmltable trthid/ththmessage/th/tr #for(fortune : fortunes) tr td#(fortune.id)/td td#escape(fortune.message)/td /tr #end /table模板通过#escape()对 message 做 HTML 转义这是 Fortunes 测试的硬性要求防止 XSS 并保证输出一致。Engine 的初始化在 EnjoyEngineConfig.java其中设置了模板根路径/templates/、ClassPath 源工厂并开启了Engine.setFastMode(true)极速模式与中文表达式支持。缓存查询测试Cache Query Test对应 CacheHandler.java。该实现复用 java-db 的缓存查询能力String sql SELECT id, randomNumber FROM world WHERE id ?; int queryCount RandomUtils.parseQueryCount(queries); int[] randomNumbers RandomUtils.randomWorldNumbers().limit(queryCount).toArray(); for (int id : randomNumbers) { Row row Db.findFirstByCache(world, id, sql, id); if (row ! null) { recordMaps.add(row.toMap()); } }Db.findFirstByCache(world, id, sql, id)表示以world为缓存名、以id为缓存键执行SELECT id, randomNumber FROM world WHERE id ?并将结果缓存命中时直接返回缓存数据。缓存的生命周期由 CacheNameService.java 定义world缓存的timeToLiveSeconds为Time.MINUTE_1 * 1010 分钟。EhCache 插件在 EhCachePluginConfig.java 中启动依赖为net.sf.ehcache:ehcache-core:2.6.11。路由注册与启动装配所有路由在 MainAppConfig.java 中统一注册。启动流程按顺序完成三件事数据库初始化读取环境变量JDBC_URL / JDBC_USER / JDBC_PSWD通过new MysqlDbConfig().init()启动 HikariCP 连接池与 ActiveRecord 插件可通过db布尔环境变量关闭数据库模板引擎与缓存启动初始化 Enjoy 引擎与 EhCache 插件路由注册通过TioBootServer.me().getRequestRouter()拿到HttpRequestRouter注册以下映射路径处理器说明/plaintextPlaintextHandler静态文本响应/jsonJsonHandler静态 JSON 响应/dbDbHandler::db单条随机主键查询/queriesDbHandler::queries按参数批量查询/updatesDbHandler::updates读改写更新/fortunesDbHandler::fortunes模板渲染/cachedQueryCacheHandlerEhCache 缓存查询注意到HttpRequestRouter.add既支持传入实现了HttpRequestHandler接口的处理器对象如 PlaintextHandler、JsonHandler、CacheHandler也支持直接传入方法引用dbController::db等这是 t-io 路由层的两种典型用法。入口类 MainApp.java 还展示了基于JDK 21 虚拟线程的线程模型装配// 1. 虚拟线程工厂用于 work 线程 OfVirtual ofVirtual Thread.ofVirtual(); ThreadFactory workTf ofVirtual.name(t-io-v-, 1).factory(); // 2. 设置 readWorkers 使用的线程工厂 TioBootServer server TioBootServer.me(); server.setWorkThreadFactory(workTf); // 3. 创建业务虚拟线程 Executor每任务一个虚拟线程 ThreadFactory bizTf Thread.ofVirtual().name(t-biz-v-, 0).factory(); ExecutorService bizExecutor Executors.newThreadPerTaskExecutor(bizTf); server.setBizExecutor(bizExecutor); TioApplication.run(MainApp.class, new MainAppConfig(), args);网络 IO 的 work 线程与业务执行线程均改为虚拟线程命名前缀分别为t-io-v-与t-biz-v-业务侧采用Executors.newThreadPerTaskExecutor实现「每任务一线程」的模型。pom.xml 中声明的java.version为 21与这一用法一致。数据库连接配置数据库初始化位于 MysqlDbConfig.java核心是HikariCP 连接池 ActiveRecord 插件的组合String jdbcUrl EnvUtils.get(JDBC_URL); String jdbcUser EnvUtils.get(JDBC_USER); String jdbcPswd EnvUtils.get(JDBC_PSWD); HikariCpPlugin hikariCpPlugin new HikariCpPlugin(jdbcUrl, jdbcUser, jdbcPswd); ActiveRecordPlugin arp new ActiveRecordPlugin(hikariCpPlugin); arp.setContainerFactory(new OrderedFieldContainerFactory()); hikariCpPlugin.start(); boolean start arp.start();连接信息全部取自环境变量也兼容app.propertiesOrderedFieldContainerFactory保证查询结果的字段顺序稳定。依赖侧由 pom.xml 提供com.litongjava:java-db:1.5.6、com.zaxxer:HikariCP:4.0.3、mysql:mysql-connector-java:5.1.46。默认配置写在 app.properties 中http.response.header.showServertrue server.port8080 server.protocolhttp JDBC_URLjdbc:mysql://tfb-database/hello_world JDBC_USERbenchmarkdbuser JDBC_PSWDbenchmarkdbpass其中tfb-database是 TechEmpower 测试环境中数据库容器的固定主机名端口与协议也可在此调整。测试 URL 一览README 明确说明所有实现使用相同的 URL全部监听在localhost:8080测试项URLPlaintext Testhttp://localhost:8080/plaintextJSON Encoding Testhttp://localhost:8080/jsonDatabase Query Testhttp://localhost:8080/dbDatabase Queries Testhttp://localhost:8080/queries?queries5Cache Query Testhttp://localhost:8080/cacheQuery?queries10000Template rendering Testhttp://localhost:8080/fortunesDatabase Update Testhttp://localhost:8080/updates?queries5这些端点与 api/tio-server-benchmark.md 中记录的接口文档一致含/db的id可选参数、/updates、/fortunes、/cacheQuery、/cacheList。同时基准测试框架通过 benchmark_config.json 中的plaintext_url、json_url、db_url、query_url、fortune_url、update_url、cached_query_url自动对拍这些路径其中query_url、update_url、cached_query_url以?queries为前缀供 wrk 脚本拼接数量参数。环境准备MySQL 8 数据库README 要求安装MySQL 8.0.32注意与 pom 中使用的 MySQL 5.1 驱动配合 8.0 服务端时的兼容性按实际环境验证给出了完整的 Docker 启动命令docker run --restartalways -d --name mysql_8 --hostname mysql \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDrobot_123456# -e MYSQL_ROOT_HOST% -e MYSQL_DATABASEhello_world \ mysql/mysql-server:8.0.32 \ --character-set-serverutf8mb4 --collation-serverutf8mb4_unicode_ci --lower_case_table_names1随后需要创建数据库 schemahello_world上述命令已通过MYSQL_DATABASE自动创建依据 README 所引用的sql/hello_world.sql建表注意该 SQL 文件不在当前仓库中需按 TechEmpower 标准的world、fortune表结构自行准备导入world10000 行与fortune测试数据。Docker 构建与运行构建镜像docker build -t tio-server-benchmark -f tio-server.dockerfile .构建过程定义在 tio-boot.dockerfile采用多阶段构建构建阶段基于litongjava/maven:3.8.8-jdk_21_0_6先mvn dependency:go-offline预下载依赖利用 Docker 层缓存再mvn package -Passembly -q打出带依赖的 fat jar运行阶段基于litongjava/jdk:21_0_6-stable-slim拷贝tio-boot-benchmark-1.0-jar-with-dependencies.jar暴露 8080 端口启动命令java -server -XX:UseNUMA -XX:UseParallelGC -cp ... com.litongjava.tio.http.server.MainApp启用 NUMA 亲和与 ParallelGC。mvn package -Passembly对应 pom.xml 中的maven-assembly-pluginjar-with-dependencies描述符将 tio-boot、java-db、fastjson2、HikariCP 等全部依赖打进单个可执行 jar。运行指定数据库docker run --rm -p 8080:8080 \ -e JDBC_URLjdbc:mysql://192.168.3.9/hello_world \ -e JDBC_USERroot \ -e JDBC_PSWDrobot_123456# \ tio-server-benchmark通过-e注入的JDBC_URL、JDBC_USER、JDBC_PSWD三个环境变量与MysqlDbConfig中EnvUtils.get(...)的读取逻辑一一对应。Windows 本地运行同样通过 JVM 直接启动 fat jar。方式一命令行传参覆盖D:\java\jdk1.8.0_121\bin\java -jar target\tio-server-benchmark-1.0.jar --JDBC_URLjdbc:mysql://192.168.3.9/hello_world?useSSLfalse --JDBC_USERroot --JDBC_PSWDrobot_123456#方式二先设置环境变量再启动set JDBC_URLjdbc:mysql://192.168.3.9/hello_world set jdbc.userroot set JDBC_PSWDrobot_123456# D:\java\jdk1.8.0_121\bin\java -jar target\tio-server-benchmark-1.0.jar说明README 中的 Windows 命令示例基于 JDK 8 与早期的target/tio-server-benchmark-1.0.jar路径而当前仓库的 pom.xml 已将java.version提升到 21Docker 产物为tio-boot-benchmark-1.0-jar-with-dependencies.jar本地运行时请按实际 JDK 与 jar 产物调整。参数风格上--JDBC_URL...这类键值传参与环境变量读取是等效的两条注入路径。构建产物与依赖清单Maven 工程定义在 pom.xml关键信息项值artifactIdtio-boot-benchmarkversion 1.0java.version21tio-bootcom.litongjava:tio-boot:2.0.6java-dbcom.litongjava:java-db:1.5.6JSON 库com.alibaba.fastjson2:fastjson2:2.0.60缓存net.sf.ehcache:ehcache-core:2.6.11连接池com.zaxxer:HikariCP:4.0.3JDBC 驱动mysql:mysql-connector-java:5.1.46日志ch.qos.logback:logback-classic:1.3.12测试junit:junit:4.12scopetest主类为com.litongjava.tio.http.server.MainApp测试目录下 MainAppTest.java 提供了EnvUtils.getBoolean(native, false)的环境变量解析示例可用于验证db、native等开关型配置的读取行为。小结tio-boot 基准测试实现展示了 t-io 生态下一套「极简但完整」的高性能服务装配方式静态响应走字节级常量缓存动态查询走 HikariCP ActiveRecord 原生查询模板渲染由 Enjoy 极速模式承载缓存查询由 EhCache 提供分钟级 TTL线程模型则由 JDK 21 虚拟线程与 NUMA 感知的 JVM 参数兜底。对于希望快速搭建同类 Web 服务、或想深入理解 t-io / tio-boot 路由与配置体系的开发者这份实现是一个可以直接对照源码研读的完整样例。赞分享性能测试测试后端开发者工具【免费下载链接】FrameworkBenchmarksSource for the TechEmpower Framework Benchmarks project项目地址https://gitcode.com/gh_mirrors/fr/FrameworkBenchmarks点击查看免费下载相关推荐t-iotio-mvc框架在 TechEmpower Framework Benchmarks 中的基准测试实现解析t iotio mvc框架在 TechEmpower Framework Benchmarks 中的基准测试实现解析 本文以 frameworks/Java性能测试测试后端开发者工具Tad.xtadx基准测试框架解析基于 Spring Boot Vert.x PostgreSQL 的 Java Web 性能测试实现Tad.xtadx基准测试框架解析基于 Spring Boot Vert.x PostgreSQL 的 Java Web 性能测试实现 导读 本文性能测试测试后端开发者工具Fortran.io 基准测试实现解析基于 FastCGI 与 nginx 的 Fortran 高性能 Web 服务方案Fortran.io 基准测试实现解析基于 FastCGI 与 nginx 的 Fortran 高性能 Web 服务方案 本指南围绕 TechEmpower性能测试测试后端开发者工具上一篇RIOT 中使用 FatFsVFS 接口测试与实践指南native 模拟与真实 SD 卡双路径下一篇DragonboatGo 语言高性能多组 Raft 共识库从入门到实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考