SpringBoot3.2 + jdk21 + GraalVM上手体验

73fc2c556461d3d2b632589aa516c028.jpeg来源:juejin.cn/post/7307522662287851558

👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍

  • 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;

截止目前,累计输出 53w+ 字,讲解图 2330+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有1900+小伙伴加入

af5838e76611b31a3a72b885e1538088.gif
  • 快速体验(二进制部署)

  • 快速体验(jar部署)

  • 对比golang

  • 对比Rust

  • 结论

3b8ecc82eb77a60571ee6dc78eb80c23.jpeg

图片
  • 可以参考官方文章进行体验:spring.io/blog/2023/0… [1]

  • 通过官方快速得到一个基于jdk21的项目:start.spring.io/ [2]

快速体验(二进制部署)

@RestController
 @SpringBootApplication
 public class DemoApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(DemoApplication.class, args);
     }
 
     @GetMapping("/customers")
     Collection<Customer> customers() {
         return Set.of(new Customer(1, "A"), new Customer(2, "B"), new Customer(3, "C"));
     }
 
     record Customer(Integer id, String name) {
     }
 }

启动非常快,秒启动

903a5078b3069e156d5ac0f820cb4e03.jpeg

图片

压测环境内存占用大概70MB左右,空闲时在20MB左右(由于直接打成二进制文件了,不能再使用jconsole、arthas之类的进行监控了),性能上由于不需要JVM预热,性能启动即巅峰。

$ ab -c 50 -n 10000 http://localhost:8080/customers
 Server Software:
 Server Hostname:        localhost
 Server Port:            8080
 
 Document Path:          /customers
 Document Length:        61 bytes
 
 Concurrency Level:      50
 Time taken for tests:   1.413 seconds
 Complete requests:      10000
 Failed requests:        0
 Total transferred:      1660000 bytes
 HTML transferred:       610000 bytes
 Requests per second:    7076.39 [#/sec] (mean)
 Time per request:       7.066 [ms] (mean)
 Time per request:       0.141 [ms] (mean, across all concurrent requests)
 Transfer rate:          1147.15 [Kbytes/sec] received
 
 Connection Times (ms)
               min  mean[+/-sd] median   max
 Connect:        0    2   8.0      2     144
 Processing:     1    5   6.7      4     147
 Waiting:        0    4   5.6      3     145
 Total:          1    7  10.4      6     149

b2e441259043afc46912513b7eaa114f.jpeg

图片

快速体验(jar部署)

jar包占用只有19MB,已经不能算是小胖jar了😊

cf4bdef57c06a28a98eda586ad2236b4.jpeg

图片

内存占用在压测时大概在200MB左右,空闲时在160MB左右。性能显然也不是启动即巅峰,可以看出其实还是需要进行JVM预热才能达到性能巅峰的

$ ab -c 50 -n 10000 http://localhost:8080/customers
 Server Software:
 Server Hostname:        localhost
 Server Port:            8080
 
 Document Path:          /customers
 Document Length:        61 bytes
 
 Concurrency Level:      50
 Time taken for tests:   17.930 seconds
 Complete requests:      10000
 Failed requests:        0
 Total transferred:      1660000 bytes
 HTML transferred:       610000 bytes
 Requests per second:    557.72 [#/sec] (mean)
 Time per request:       89.651 [ms] (mean)
 Time per request:       1.793 [ms] (mean, across all concurrent requests)
 Transfer rate:          90.41 [Kbytes/sec] received
 
 Connection Times (ms)
               min  mean[+/-sd] median   max
 Connect:        0   38 430.2      2    7004
 Processing:     0   14  90.4      8    1773
 Waiting:        0   12  88.7      6    1771
 Total:          1   53 439.0     10    7011

4876e78b0cd16351d3ac1bc0ce7fc1f5.jpeg

图片

对比golang

package main
 
 import (
     "encoding/json"
     "flag"
     "fmt"
     "net/http"
 )
 
 var port = flag.String("p", "8080", "please input port")
 
 func main() {
     http.HandleFunc("/customers", func(writer http.ResponseWriter, request *http.Request) {
         data, _ := json.Marshal(request.URL)
         writer.Write(data)
     })
     e := make(chan error)
     go func() {
         e <- fmt.Errorf("error[%v]", http.ListenAndServe(":"+*port, nil))
     }()
     fmt.Println("http 服务器启动...")
     fmt.Println(<-e)
 }

这里golang没有使用框架,仅使用标准库,所以内存占用较低,仅10MB左右,不过即使使用Gin之类的web框架,内存也不会超过20MB

$ ab -c 50 -n 10000 http://localhost:8080/customers
 Server Software:
 Server Hostname:        localhost
 Server Port:            8080
 
 Document Path:          /customers
 Document Length:        161 bytes
 
 Concurrency Level:      50
 Time taken for tests:   1.380 seconds
 Complete requests:      10000
 Failed requests:        0
 Total transferred:      2790000 bytes
 HTML transferred:       1610000 bytes
 Requests per second:    7247.68 [#/sec] (mean)
 Time per request:       6.899 [ms] (mean)
 Time per request:       0.138 [ms] (mean, across all concurrent requests)
 Transfer rate:          1974.71 [Kbytes/sec] received
 
 Connection Times (ms)
               min  mean[+/-sd] median   max
 Connect:        0    2  16.5      2     459
 Processing:     0    4  27.9      2     460
 Waiting:        0    2  10.5      2     459
 Total:          1    7  32.3      4     462

dbeebedd8e94a01855d972d1f688e1a9.jpeg

图片

对比Rust

[dependencies]
actix-web = "4"
use actix_web::{get, App, HttpRequest, HttpResponse, HttpServer, Responder};

#[get("/customers")]
async fn echo(req: HttpRequest) -> impl Responder {
    let url = req.uri().to_string();
    HttpResponse::Ok().body(url)
}


#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(echo)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

Actix-web空闲时内存占用大概3MB左右,压测时占用大概6MB左右

$ ab -c 50 -n 10000 http://localhost:8080/customers
Server Software:
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /customers
Document Length:        10 bytes

Concurrency Level:      50
Time taken for tests:   1.091 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      860000 bytes
HTML transferred:       100000 bytes
Requests per second:    9163.48 [#/sec] (mean)
Time per request:       5.456 [ms] (mean)
Time per request:       0.109 [ms] (mean, across all concurrent requests)
Transfer rate:          769.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2  11.0      2     189
Processing:     0    3   7.0      3     190
Waiting:        0    2   7.0      2     189
Total:          2    5  13.1      4     193

46843907fe575bc9ede865d8e91a47f4.jpeg

图片

rust虽然有非常厉害的零成本抽象,但作为代价其编译时间会比较长(在实际项目中真的特别长😢)

$ time cargo build
cargo build  213.00s user 23.08s system 258% cpu 1:31.39 total

结论

AOT-processed已经相对成熟,效果可以说非常惊艳,解决了JVM启动慢、需要预热、内存占用大等问题。

美中不足的是编译速度非常慢,笔者电脑是2017款mac book pro编译花费大概15分钟左右

Finished generating 'demo' in 14m 33s.
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESS
 [INFO] ------------------------------------------------------------------------
 [INFO] Total time:  15:45 min
 [INFO] Finished at: 2023-12-01T17:00:21+08:00
 [INFO] ------------------------------------------------------------------------
[INFO] Total time: 15:45 min [INFO] Finished at: 2023-12-01T17:00:21+08:00 
[INFO] ------------------------------------------------------------------------

可以看出java在云原生大环境下已经取得了不错的进步的

👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍

  • 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;

截止目前,累计输出 53w+ 字,讲解图 2330+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有1900+小伙伴加入

1dd14e36bb574f0762ebb7e10b741f23.gif

291f14811d894f74b58c76247af17070.jpeg

 
 

c72351a7185d3b670329a0054b4c4085.gif

 
 
 
 
1. 我的私密学习小圈子~
2. Nginx 限速模块大揭秘
3. 架构设计中如何应对接口级故障?
4. 为何 JetBrains 公司做 IDE 就可以养活自己,而国内公司却很难做到?
 
 
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。
点“在看”支持小哈呀,谢谢啦
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值