简单性能测试:springboot-2.x vs actix-web-4.x benchmark - funnyZpC
source link: https://www.cnblogs.com/funnyzpc/p/15956465.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
性能测试:springboot-2.x vs actix-web-4.x benchmark
转载请注明出处 https://www.cnblogs.com/funnyzpc/p/15956465.html
本次是对两款web框架做一次性能测试,这个测试做的很早,约在两个月前(也是actix-web4.0刚刚发布之后),目的是 比较有gc类web框架(springboot
)与无gc类web框架(actix-web
)的性能,分为带db查询
与不带db查询
这两种情况,简单探究下web框架的性能瓶颈在哪儿,仅此而已。
顺带说下,apache JMeter
实在太垃圾...,这里不细说了诶~ 🙄️
-
-c 表示并发数 -n 每个并发执行请求的次数,总请求的次数 = 并发数 * 每个并发执行请求的次数 -u 需要压测的地址
-
window 10
系统 8核32GB
-
测试项目地址(springboot需自行添加代码)
准备测试代码及数据
-
springboot2(java)
@RestController public class Echo2Controller { @Autowired public DB1SQLDao db1SQLDao; // 带db资源的 @GetMapping("/echo2") public Map<String,Object> echo(){ /* <select id="findList2" resultType="java.util.Map"> SELECT id,name,show_flag,create_date,code,parent_code from sys_menu limit 2 </select> */ List result = db1SQLDao.query("com.mee.xml1.tmp.findList2"); Map<String, Object> res = ResultBuild.success("success"); res.put("data",result); return res; } // 不带DB资源的 @GetMapping("/echo3") public Map<String,Object> echo3(){ /* public static final Map<String,Object> SUCCESS = new HashMap<String,Object>(2,1){{ put("status",1); put("msg","成功"); }}; */ return ResultBuild.SUCCESS; } }
-
actix-web4(rust)
// 仅json资源请求 pub async fn echo() -> HttpResponse{ return HttpResponse::Ok().json(ResultBuild::<&str>::success()); } // 带db的资源请求 pub async fn sys_menu_list(/*req_body: String,*/db: web::Data<Pool>) -> HttpResponse{ // async fn echo(/*req_body: String*/db: web::Data<Pool>) ->impl Responder { // let mut conn=db.get().await.unwrap(); // let rows=conn.query("select * from sys_menu ",&[]).await.unwrap(); // // get参数可以是str,也可以是i32,获取第几个。但是必须要指明获取的类型 // let sys_menus = menu_list(&db).await.expect("---error---"); let sys_menu_list = menu_list(&db).await; // HttpResponse::Ok().json(sys_menus) return HttpResponse::Ok().json(ResultBuild::success_with_data(sys_menu_list)); } async fn menu_list(pool: &Pool) -> Vec<SysMenu> { let client: Client = pool.get().await.expect("---error---"); let stmt = client.prepare_cached("SELECT id,name,show_flag,create_date,code,parent_code from sys_menu limit 2").await.expect("--error2--"); let rows = client.query(&stmt, &[]).await.expect("--error3"); rows .into_iter() .map(|row| SysMenu { id: row.get(0), name: row.get(1), show_flag: row.get(2), create_date: row.get(3), code: row.get(4), parent_code: row.get(5), }) .collect() }
-
CREATE TABLE "sys_menu" ( "id" numeric(24) primary key, "name" varchar(100) COLLATE "pg_catalog"."default" NOT NULL, "show_flag" int2 NOT NULL, "create_date" timestamp(6) NOT NULL, "create_by" varchar(64) COLLATE "pg_catalog"."default" NOT NULL, "code" varchar(8) COLLATE "pg_catalog"."default", "parent_code" varchar(8) COLLATE "pg_catalog"."default" ); COMMENT ON TABLE "public"."sys_menu" IS '系统::菜单表'; INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20010616453200802', '主页', 1, '2020-11-27 03:09:21.714105', 'sys', '01', NULL); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20010616513800803', '功能2', 1, '2020-11-27 03:09:24.25396', 'sys', '02', NULL); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20010616525500804', '功能1', 1, '2020-12-09 11:44:04.478717', 'sys', '03', NULL); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20010616545400805', '系统配置', 1, '2020-11-27 03:09:29.581216', 'sys', '04', NULL); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20082918550500800', '系统配置', 1, '2020-11-27 03:09:40.177621', 'sys', '0401', '04'); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20082918561500801', '基础管理', 1, '2020-11-27 03:09:36.788131', 'sys', '0402', '04'); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20082918572200802', '用户配置', 1, '2020-11-27 03:09:42.242687', 'sys', '040101', '0401'); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20082918574400803', '菜单配置', 1, '2020-11-27 03:09:44.198666', 'sys', '040103', '0401'); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20082918574400813', '角色分配', 1, '2020-11-27 03:09:47.713889', 'sys', '040102', '0401'); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20082918581000804', '字典配置', 1, '2020-11-27 03:09:49.643454', 'sys', '040201', '0402'); INSERT INTO "public"."sys_menu"("id", "name", "show_flag", "create_date", "create_by", "code", "parent_code") VALUES ('20082918584500805', '日志配置', 1, '2020-11-27 03:09:52.519771', 'sys', '040202', '0402');
1.1带DB资源的请求 (8c-8w)
目标资源通过数据库查询并序列化为json返回
- 测试命令
go-stress-testing-win -c 8 -n 80000 -u http://127.0.0.1:8011/mee_auto/echo2 go-stress-testing-win -c 8 -n 80000 -u http://127.0.0.1:8080/echo
springboot (8c)
─────┬───────┬────────┬────────┬────────┬────────┬─────────┬─────────┬──────────┬─────────┬────────
耗时 │ 并发数 │ 成功数 │ 失败数 │ qps │ 最长耗时 │ 最短耗时 │ 平均耗时 │ 下载字节 │ 字节每秒 │ 错误码
─────┼───────┼───────┼────────┼─────────┼──────────┼──────────┼─────────┼─────────┼─────────┼────────
163s│ 8│ 79453│ 0│ 505.33 │ 454.05 │ 6.45 │ 15.83 │ │ │200:79453
164s│ 8│ 79911│ 0│ 505.41 │ 454.05 │ 6.45 │ 15.83 │ │ │200:79911
164s│ 8│ 80000│ 0│ 505.43 │ 454.05 │ 6.45 │ 15.83 │ │ │200:80000
************************* 结果 stat ****************************
处理协程数量: 8
请求总数(并发数*请求数 -c * -n): 80000 总请求时间: 164.398 秒 successNum: 80000 failureNum: 0
************************* 结果 end ****************************
actix-web (8c)
─────┬───────┬───────┬───────┬────────┬────────┬────────┬─────────┬────────┬──────────┬────────
耗时 │ 并发数│ 成功数 │ 失败数│ qps │ 最长耗时│ 最短耗时 │ 平均耗时 │ 下载字节│ 字节每秒 │ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼─────────┼────────┼─────────┼────────
135s│ 8│ 79025│ 0│ 610.44│ 112.56│ 5.30│ 13.11 │22,601,150│ 167,412│200:79025
136s│ 8│ 79617│ 0│ 610.49│ 112.56│ 5.30│ 13.10 │22,770,462│ 167,428│200:79617
137s│ 8│ 80000│ 0│ 610.67│ 112.56│ 5.30│ 13.10 │22,880,000│ 167,155│200:80000
************************* 结果 stat ****************************
处理协程数量: 8
请求总数(并发数*请求数 -c * -n): 80000 总请求时间: 136.878 秒 successNum: 80000 failureNum: 0
************************* 结果 end ****************************
1.2带DB资源的请求 (16c-8w)
目标资源通过数据库查询并序列化为json返回
- 测试命令
go-stress-testing-win -c 16 -n 80000 -u http://127.0.0.1:8011/mee_auto/echo2 go-stress-testing-win -c 16 -n 80000 -u http://127.0.0.1:8080/echo
springboot (16c)
─────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────
耗时 │ 并发数 │ 成功数 │ 失败数 │ qps │ 最长耗时│ 最短耗时│ 平均耗时│ 下载字节│ 字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────
146s│ 16│ 79294│ 0│ 558.06│ 553.22│ 8.20│ 28.67│ │ │200:79294
147s│ 16│ 79861│ 0│ 558.22│ 553.22│ 8.20│ 28.66│ │ │200:79861
147s│ 16│ 80000│ 0│ 558.07│ 553.22│ 8.20│ 28.67│ │ │200:80000
************************* 结果 stat ****************************
处理协程数量: 16
请求总数(并发数*请求数 -c * -n): 80000 总请求时间: 147.496 秒 successNum: 80000 failureNum: 0
************************* 结果 end ****************************
actix-web (16c)
─────┬───────┬───────┬───────┬────────┬─────────┬─────────┬────────┬──────────┬─────────┬────────
耗时│ 并发数 │ 成功数 │ 失败数│ qps │ 最长耗时 │最短耗时 │ 平均耗时 │ 下载字节 │ 字节每秒 │ 错误码
─────┼───────┼───────┼───────┼────────┼─────────┼─────────┼────────┼──────────┼─────────┼────────
139s│ 16│ 79468│ 0│ 584.20│ 259.02 │ 9.46 │ 27.39│22,727,848│ 163,508 │200:79468
140s│ 16│ 79991│ 0│ 584.31│ 259.02 │ 8.97 │ 27.38│22,877,426│ 163,408 │200:79991
140s│ 16│ 80000│ 0│ 584.33│ 259.02 │ 8.97 │ 27.38│22,880,000│ 163,248 │200:80000
************************* 结果 stat ****************************
处理协程数量: 16
请求总数(并发数*请求数 -c * -n): 80000 总请求时间: 140.155 秒 successNum: 80000 failureNum: 0
************************* 结果 end ****************************
2.1不带DB资源的请求 (16c-16w)
目标资源仅仅为对象序列化为json返回
- 测试命令
go-stress-testing-win -c 16 -n 160000 -u http://127.0.0.1:8011/mee_auto/echo3 go-stress-testing-win -c 16 -n 160000 -u http://127.0.0.1:8080/echo3
springboot (16c)
─────┬───────┬───────┬────────┬────────┬────────┬─────────┬────────┬─────────┬────────┬────────
耗时│ 并发数 │ 成功数 │ 失败数 │ qps │ 最长耗时│ 最短耗时│ 平均耗时│ 下载字节 │ 字节每秒 │ 错误码
─────┼───────┼───────┼────────┼────────┼────────┼────────┼─────────┼────────┼────────┼────────
74s│ 16│ 157047│ 0 │ 2705.19│ 283.33│ 0.50│ 5.91 │ │ │200:157047
75s│ 16│ 158698│ 0 │ 2696.52│ 283.33│ 0.50│ 5.93 │ │ │200:158698
76s│ 16│ 160000│ 0 │ 2693.35│ 283.33│ 0.50│ 5.94 │ │ │200:160000
************************* 结果 stat ****************************
处理协程数量: 16
请求总数(并发数*请求数 -c * -n): 160000 总请求时间: 75.811 秒 successNum: 160000 failureNum: 0
************************* 结果 end ****************************
actix-web (16c)
─────┬───────┬───────┬───────┬────────┬────────┬─────────┬────────┬──────────┬────────┬────────
耗时│ 并发数 │ 成功数 │ 失败数│ qps │ 最长耗时│ 最短耗时 │ 平均耗时│ 下载字节 │ 字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼─────────┼────────┼──────────┼────────┼────────
43s│ 16│ 155741│ 0│ 4620.61│ 113.40│ 0.64 │ 3.46│9,811,683 │ 228,177│200:155741
44s│ 16│ 158948│ 0│ 4608.00│ 113.40│ 0.64 │ 3.47│10,013,724│ 227,583│200:158948
44s│ 16│ 160000│ 0│ 4609.79│ 113.40│ 0.89 │ 3.47│10,080,000│ 227,478│200:160000
************************* 结果 stat ****************************
处理协程数量: 16
请求总数(并发数*请求数 -c * -n): 160000 总请求时间: 44.312 秒 successNum: 160000 failureNum: 0
************************* 结果 end ****************************
2.2不带DB资源的请求 (8c-8w)
目标资源仅仅为对象序列化为json返回
- 测试命令
go-stress-testing-win -c 8 -n 80000 -u http://127.0.0.1:8011/mee_auto/echo3 go-stress-testing-win -c 8 -n 80000 -u http://127.0.0.1:8080/echo3
springboot (8c)
─────┬───────┬───────┬───────┬────────┬────────┬────────┬─────────┬────────┬────────┬────────
耗时 │ 并发数 │ 成功数 │失败数 │ qps │最长耗时│最短耗时 │平均耗时 │下载字节│字节每秒 │ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼─────────┼────────┼────────┼────────
52s│ 8│ 76730│ 0│ 1820.31│ 253.83│ 0.30│ 4.39 │ │ │200:76730
53s│ 8│ 78467│ 0│ 1826.48│ 253.83│ 0.30│ 4.38 │ │ │200:78467
54s│ 8│ 80000│ 0│ 1834.15│ 253.83│ 0.30│ 4.36 │ │ │200:80000
************************* 结果 stat ****************************
处理协程数量: 8
请求总数(并发数*请求数 -c * -n): 80000 总请求时间: 53.885 秒 successNum: 80000 failureNum: 0
************************* 结果 end ****************************
actix-web (8c)
──────┬───────┬───────┬────────┬───────┬─────────┬─────────┬─────────┬─────────┬────────┬────────
耗时 │并发数 │ 成功数 │ 失败数 │ qps │ 最长耗时│ 最短耗时│ 平均耗时│ 下载字节 │ 字节每秒 │ 错误码
─────┼───────┼───────┼────────┼────────┼─────────┼────────┼─────────┼──────────┼────────┼────────
12s│ 8│ 69187│ 0 │ 7257.03│ 5.98 │ 1.00│ 1.10 │4,358,781 │ 363,207│200:69187
13s│ 8│ 74735│ 0 │ 7232.76│ 5.98 │ 0.99│ 1.11 │4,708,305 │ 362,149│200:74735
14s│ 8│ 80000│ 0 │ 7229.78│ 5.98 │ 0.00│ 1.11 │5,040,000 │ 361,557│200:80000
************************* 结果 stat ****************************
处理协程数量: 8
请求总数(并发数*请求数 -c * -n): 80000 总请求时间: 13.940 秒 successNum: 80000 failureNum: 0
************************* 结果 end ****************************
请求一览【带DB数据请求】
并发数 | 并发请求数 | 框架 | qps | 平均耗时 |
---|---|---|---|---|
8 | 80000 | springboot | 505 | 15.83 |
8 | 80000 | actix-web | 610 | 13.10 |
16 | 80000 | springboot | 558 | 28.66 |
16 | 80000 | actix-web | 584 | 27.38 |
请求一览【不带DB数据请求(纯代码json)】
并发数 | 并发请求数 | 框架 | qps | 平均耗时 |
---|---|---|---|---|
8 | 80000 | springboot | 1826 | 4.38 |
8 | 80000 | actix-web | 7232 | 1.11 |
16 | 160000 | springboot | 2696 | 5.93 |
16 | 160000 | actix-web | 4609 | 3.47 |
首先一个重要的前提是我的电脑是 i5 8核32GB 的配置
-
1.在带DB数据请求的下,不管是8个并发还是16个并发
springboot
与actix-web
两者的qps
相距并不大,在cpu超载(16c)下平均耗时更多,据此可以得出 并发数与所在的机器配置是成正比的:硬件配置在其合理的并发下性能以及延迟是最优的 -
2.在不带DB的数据请求下,也显示了
1
的结论,同时也能看到随着cpu超载延迟
以及qps
也会逐渐变得糟糕
-
3.对于springboot、actix-web这两款框架,无gc类语言在合适的并发&硬件配置下 性能(
延迟
、qps
、内存
、cpu利用率
)相对与gc
类框架是存在优势的 -
4.对于web类框架(不管是gc类的还是非gc类的框架)他们的性能除了并发&硬件配置外 也取决于整个请求链路中性能最低的那一环:通过以上可以大致分析出性能一般是出在DB数据查询这一块儿,所以良好的DB架构及缓存配置可以有效提高应用的性能及硬件的利用率
以上仅为个人测试所得结果,如有谬误恳请指正~ 😊
Recommend
-
2
dolphinscheduler简单任务定义及跨节点传参 转载请注明出处 https://www.cnblogs.com/funnyzpc/p/16395094.html ...
-
4
ArrayList分析1-循环、扩容、版本 转载请注明出处 https://www.cnblogs.com/funnyzpc/p/16407733.html 前段时间抽空看了下
-
3
ArrayList分析2 : Itr、ListIterator以及SubList中的坑 转载请注明出处:ht...
-
2
datax开启hana支持以及dolphinscheduler开启datax任务 前面(@,@) 前段时间因为要做异构数据导入导出,所以搜了下,发现这类工具收费的居多,使用起来未必趁手~ 于是我找...
-
3
dolphinscheduler添加hana支持 转载请注明出处: https://www.cnblogs.com/funnyzpc/p/16395092.html 上一节有讲datax
-
5
Yaf 2.1性能测试(Yaf 2.1 Benchmark) 本文地址: https://www.laruence.com/2011/12/02/2333.html 转载请注明出处
-
3
Go 语言测试(Test)、性能测试(Benchmark) 学习笔记 cchd0001 · 2015-12-14 18:00:00 · 31388 次点击 · 预计阅读时间 2 分钟 · 大约8小时之前 开始浏览 ...
-
6
通过 Rodinia Benchmark 测试 GPU 性能并使用 GPGPU-Sim 仿真 29 Jan 2022 2498字 9分
-
93
README.md Actix
-
23
For the past year or more, I've been passively watching the progress of the "async/await" implementation in the Rust programming language. Though I can't speak to the technical det...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK