Quarkus 云原生java框架

介绍

Red Hat开源的Java框架Quarkus, 为 GraalVM 和 HotSpot 量身定制用程序。

启动超快,内存极低(不仅是堆大小!)在容器编排平台(如Kubernetes)中提供了近乎即时的向上扩展和高密度的内存利用率。我们使用一种称为编译时启动技术

用不用 Native

谈Quarkus绕不开native(native可执行文件的构建)。没办法,官方先来的,首页就是大大的native/jvm性能对比。
native实测是真的快(不到0.1s),内存占用也确实小(启动几十MB,跑一段时间稳定大概300MB附近,不过不同压力的不同类型服务也不能说明什么)。但有什么缺点?

  • 编译速度慢 :一个比较简单的web服务,在我们CICD的机器上编译大概需要4min,如果是容器内multistage编译则时间更长,但直接编译对环境又有要求,所以还是最好有更强大的编译机器。

  • 编译产物体积大 :我们编译出来的二进制文件大约130-150MB,upx 压缩后40MB以内;单看最后的docker镜像,如果用最小的基础镜像,大约整个镜像可以做到100MB以内,是挺小的;但是每次构建变更的layer,都是整个二进制文件的变更,也就是没次编译多了一个40MB的layer出来,体积相当可观。同样的服务,如果打jar,真正变更的只有不到1MB,pod拉镜像的速度会更快,对docker仓库的压力也更小。

  • 开发多了不少限制 :你要注意新引入的依赖是不是支持native的;所以可能需要json序列化反序列化的类记得加上 @RegisterForReflection 注解;如果是外部依赖的实体类,要编写一个什么json文件声明要处理…………本文不是Quarkus教程,就不详细展开了,总之,如果要native,最好整个服务都只用quarkus生态里面的依赖,否则你不知道什么时候就编译不了了。虽然quarkus的生态已经比较完善,但总有没cover到的地方,比如hadoop生态的sdk。

响应式

  • Quarkus core基于Vert.X实现,是响应式的,这也是它能unify命令式和响应式的关键原因,也是各个扩展能自行选择命令式实现和响应式实现的原因
  • Quarkus在Vert.X基础上做了一个路由层来兼容两种实现,像HTTP请求这种直接通过路由层、如果是响应式代码,直接在I/O线程上执行;命令式代码则丢到Worker线程执行(就要做上下文切换了);至于Quarkus怎么知道是什么实现,就看方法注解以及签名了,具体不展开
  • 也就是说,至少在http接口这一层面,开发者可以选择用命令式还是响应式编程实现,另外定时任务、Eventbus之类也是支持的
  • 但到了ORM层只能有一个选择,是的, Hibernate 和 Hibernate-reactive 显然不能共存。

参考:
https://leibnizhu.github.io/p/%E5%85%B3%E4%BA%8EQuarkus%E7%9A%84%E7%A2%8E%E7%A2%8E%E5%BF%B5/