云原生Java框架—Quarkus

这篇具有很好参考价值的文章主要介绍了云原生Java框架—Quarkus。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、简介

Quarkus是由Red Hat公司于2018年开始研发的一款面向云原生的Java开发框架,旨在使 Java 成为Kubernetes 和无服务环境中的领先平台,目前最新版本为2.3.0,已生产可用。主要特点是:

  1. 云原生:支持通过GraalVM Native-Image将Java应用打包成本地二进制镜像,减少内存使用、缩短应用启动时间

  2. 低使用成本:与常见的Java标准、框架等协同工作,如:Spring、Hibernate、Netty、RestEasy等,无需学习新的标准和规范

  3. 高开发效率:代码热更新,无需重启即可查看代码改动的结果(dev环境下),支持单元测试、本地debug等

  4. 同时支持命令式和响应式代码

  5. 支持同时运行在GraalVM和HotSpot两种虚拟机上

云原生Java框架—Quarkus

 

Quarkus运行时内存、启动时间对比

二、背景—Quarkus的初衷

2.1 困境

在JVM上运行企业级Java应用所需的漫长初始启动时间和庞大的内存消耗无法完美适应云原生的需要

  1. Java虚拟机的设计本身是为了满足长时间稳定运行的服务,而K8S、Serverless等场景下需要应用快速灵活的启动、销毁,难以长时间稳定运行,导致JIT编译器在程序启动时占用了比较多的时间但却很难在运行时发挥出威力。例如:AWS的Lambda函数支持的最长运行时间是15min(刚开始时仅支持5min的运行时间)。
    云原生Java框架—Quarkus

     

  2. 从上图可以看出:应用程序在启动过程中,类加载和JIT编译消耗了比较多的时间。
    JIT原理简介:
    云原生Java框架—Quarkus

  3. 容器环境下,每个Java应用程序启动时都需要先启动Docker容器,然后在Docker内启动JVM,最后JVM再加载应用,整个过程耗时较长

  4. 打包的镜像中,JDK动辄上百兆,远大于应用本身的大小

  5. 构建的镜像中存在大量运行时未使用的代码和依赖

  6. 内存占用大,一个空的Spring Web内存占用约为122MB左右,而Go Web应用在10MB左右 GraalVM多语言架构

2.2 契机

GraalVM的出现为Java开发者拥抱云原生打开了一扇窗户 GraalVM是Oracle发布的通用型虚拟机,当然也可以用来运行Java程序,被称为下一代Java虚拟机。2016年6月发布第一个release版本。主要特点是:

  • 高性能:GraalVM 的高性能AOT 编译器支持在构建阶段生成可直接运行的本地代码,由于一系列高级的编译器优化和积极的内联技术,使得生成的本地代码运行速度更快,产生的垃圾和占用的CPU均 更少,可极大降低云和基础设施的成本。同时,由于没有使用JIT运行时优化,程序在启动时即可达到峰值性能,不需要预热时间。

    云原生Java框架—Quarkus

    AOT编译过程

    官方数据:在Renaissance 基准测试套件中,GraalVM 企业版实现了比 OpenJDK 8 高 1.55 倍的几何平均加速,以及与 OpenJDK 11 类似的结果。

  • 多语言:支持多种语言编写的程序运行在GraalVM上并且支持多种语言之间互相调用

    云原生Java框架—Quarkus

    GraalVM多语言架构

    GraalVM支持多语言的原理:将其他语言编译成 .class文件
    云原生Java框架—Quarkus

  • 快速启动、减少内存使用:GraalVM 0.20版本开始出现的一个极小型(相比于HotSpot)的运行时环境Substrate VM:1. 完全脱离了HotSpot虚拟机,拥有独立的运行时,包含异常处理,同步,线程管理,内存管理(垃圾回收)和JNI等组件;2. 在AOT编译时已保存初始化好的堆快照,并支持内存占用对比启动时间对比从程序入口直接开始运行。

    内存占用对比

    云原生Java框架—Quarkus

    启动时间对比

    云原生Java框架—Quarkus
  • 完善的工具:提供了丰富的开发工具,用于Java及其他语言的Debug、监控、Profile及资源消耗优 化

参考资料:InfoQ Quarkus Java框架答疑,周志明—云原生时代的Java

三、困难与挑战—封闭的程序空间

传统的Java程序空间是开放的,即完全可以在运行时动态的加载配置、类等资源并进行初始化。但GraalVM进行Native-Image打包时,需要在构建过程中将程序运行时用到的所有类、资源等初始化好并以堆内存快照的形式保存起来,即Native-Image要求程序的运行空间必须是封闭的。实际上,SubstrateVM在构建Native-Image的阶段将探索程序的整个编译空间,并通过静态分析的方法推算出所有调用的 目标方法,最终将所有推算出的方法都纳入编译范围,这将导致动态加载其他类库、反射、动态代理和CGlib代理等功能无法正常使用。例如:传统的程序支持运行时,根据用于传入的类全限定名和方法来动态加载类并反射调用目标方法,这种功能如何在AOT编译阶段实现?

3.1 如何解决反射的使用

  • 自动检测:静态分析器主动拦截诸如: Class.forName(String) , Class.forName(String, ClassLoader) , Class.getDeclaredField(String) , Class.getField(String) , Class.getDeclaredMethod(String, Class[]) , Class.getMethod(String, Class[]) , Class.getDeclaredConstructor(Class[]) , and Class.getConstructor(Class[]) )等方 法,如果字符串可以被替换成常量,则直接在构建阶段将其替换,如果检测出错误,则直接将对应的代码替换成错误。

  • 手动配置:在配置文件中配置运行时需要被反射访问到的类,示例:

    [
        {
            "name" : "java.lang.Class",
            "allDeclaredConstructors" : true,
            "allPublicConstructors" : true,
            "allDeclaredMethods" : true,
            "allPublicMethods" : true,
            "allDeclaredClasses" : true,
            "allPublicClasses" : true
        },
        {
            "name" : "java.lang.String",
            "fields" : [
                { "name" : "value" },
                { "name" : "hash" }
            ],
            "methods" : [
                { "name" : "<init>", "parameterTypes" : [] },
                { "name" : "<init>", "parameterTypes" : ["char[]"] },
                { "name" : "charAt" },
                { "name" : "format", "parameterTypes" : ["java.lang.String", "java.lang.Object[]"] }
            ]
        },
        {
            "name" : "java.lang.String$CaseInsensitiveComparator",
            "methods" : [
                { "name" : "compare" }
            ]
        }
    ]
  • native-image-agent收集:在项目常规运行期间,用agent与JVM交互,拦截所有查找类、方法、字段、资源或者请求代理访问的调用。然后agent将在指定的目录下生成以下文件:jniconfig.json,reflect-config.json,proxy-config.json以及resource-config.json等。

3.2 如何使用动态代理(不支持使用CGLib代理)

  • 自动检测:静态分析器主动拦截诸如: java.lang.reflect.Proxy.newProxyInstance(ClassLoader, Class<?>[],InvocationHandler)and java.lang.reflect.Proxy.getProxyClass(ClassLoader,Class<?>[])等方法的调用,获取代理接口数组的值。

  • 手动配置:在配置文件中配置运行时动态代理需要用到的类

    [
        ["java.lang.AutoCloseable", "java.util.Comparator"],
        ["java.util.Comparator"],
        ["java.util.List"]
    ]

    3.3 其他问题

    • AOT编译需要更长的时间(几十分钟),需要消耗更多的内存(几十GB)

    • 提前初始化并不总是安全的

    class A {
        static B b = new B();
    }
    class B {
        static {
            C.dosomething();
        }
    }
    class C {
        static long currentTime;
        static {
            currentTime=System.currentTimeMillis();
        }
        static void dosomething(){…}
    }

    显示指定需要在运行时初始化的类。 参考资料:Static Compilation of Java Applications at Alibaba at Scale、阿里巴巴的GraalVM Nativeimage

    四、简单示例

    4.1 QuickStart

    • Quarkus + Native、Quarkus + JVM、Traditional SpringCloud 启动时间、消耗内存的比较

    • 使用 native-image-agent 自动生成Reflect、DynamicProxy等文件文章来源地址https://www.toymoban.com/news/detail-478245.html

    4.2 Dubbo支持GraalVM打包成Native Image

    4.3 Quarkus+GraalVM应用上线

到了这里,关于云原生Java框架—Quarkus的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • TensorFlow是由Google开发的开源深度学习框架

    TensorFlow是由Google开发的开源深度学习框架。它提供了一种灵活而高效的方式来构建和训练神经网络模型。 TensorFlow的基本概念包括: Tensor:TensorFlow中的核心数据结构,表示多维数组。可以是标量、向量、矩阵或更高维度的张量。 图(Graph):TensorFlow使用图来表示计算任务。

    2024年01月16日
    浏览(49)
  • windows下体验quarkus原生编译打包

    本机是 win10 GraalVM 21.0.2,用的社区版的最新版本,并配置其 bin 目录加入环境变量 Maven 3.9.6,用的最新版本 IDEA ,本机版本 2023.2.5 Visual Studio 2022 17.9.2,用的社区版最新版本, quarkus 官网提到过Visual Studio 2017 Visual C++ Build Tools,可能2017或更高版本的这个也可以,但是由于本机早

    2024年03月09日
    浏览(49)
  • 基于JAVA公司介绍网站设计与实现(Springboot框架) 研究背景与意义、国内外研究现状

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年02月03日
    浏览(43)
  • [Java Web]element | 一个由饿了么公司开发的前端框架,让你快速构建现代化、美观的 Web 应用程序。

    ⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章 ⭐作者主页:@逐梦苍穹 ⭐所属专栏:Java Web ⭐如果觉得文章写的不错,欢迎点个关注一键三连😉有写的不好的地方也欢迎指正,一同进步😁 https://element.eleme.cn/#/zh-CN/component/installation   Element 是

    2024年02月05日
    浏览(97)
  • 【JAVA日志框架】JUL,JDK原生日志框架详解。

    前言 Java日志体系混乱?Java日志框架系列,清晰简洁整理好整个Java的日志框架体系。第一篇,JDK原生日志框架——JUL。 目录 1.概述 2.日志级别 3.配置 4.继承关系 日志框架的核心问题: 日志是用来记录应用的一些运行信息的。假设没有日志框架,我们要在应用里手动实现日志

    2024年02月04日
    浏览(45)
  • Java 集合框架体系简介

    存储多个数据可以使用数组,但由于数组在内存中是连续存储的,所以会有一些限制。比如数组在创建时就要指定长度,即可以容纳的元素个数,且指定后无法更改;数组在创建时需要指定元素的类型,并且所有元素都必须是该类型或其子类;添加或删除数组中的元素需要创

    2024年02月08日
    浏览(49)
  • Altera&Xilinx公司FPGA简介

    Intel/Altera 系列FPGA简介 - 知乎 (zhihu.com) Altera FPGA 提供了多种可配置嵌入式 SRAM、高速收发器、高速 I/O、逻辑模块以及布线。其内置知识产权 (IP) 结合优秀的软件工具,缩短了 FPGA 开发时间,降低了功耗和成本。 Altera FPGA 非常适合从大批量应用到目前最新产品的各类应用。每一

    2024年02月05日
    浏览(46)
  • 支持JDK19虚拟线程的web框架,之四:看源码,了解quarkus如何支持虚拟线程

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇是《支持JDK19虚拟线程的web框架》系列的第四篇,主要内容是阅读quarkus源码,开阔眼界,了解框架级别的软件是如何使用虚拟线程的,另外再感受一下整体架构设计的重要性,只有良好的设计才

    2024年02月08日
    浏览(49)
  • 【云原生技术】云计算中一些常见的Java框架和工具

    开发语言、框架以及应用类型之间的关系通常取决于开发人员的需求和项目的特定要求。以下是对这些概念的详细介绍: 1. 开发语言: 开发语言是编写应用程序的基本工具。不同的开发语言具有不同的语法和特性,以适应不同的开发需求。一些常见的开发语言包括: Python

    2024年01月22日
    浏览(47)
  • 云原生明星创业公司 Weaveworks 倒闭了,GitOps 该何去何从?

    自从 2009 年 DevOps 面世以来,xOps 的潘多拉魔盒就被打开了,AIOps、DataOps、DevSecOps、BizDevOps,当然还有最近几年比较火热的 GitOps。但是很不幸的是,就在龙年新春前夕,GitOps 理论提出者—— Weaveworks 倒下了。 时间回到 2 月 5 日,就在大家期待春节长假的时候,一则 Weaveworks

    2024年02月22日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包