我的编程空间,编程开发者的网络收藏夹
学习永远不晚

云原生Java框架—Quarkus

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

云原生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两种虚拟机上

 

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

二、背景—Quarkus的初衷

2.1 困境

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

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

     

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

  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运行时优化,程序在启动时即可达到峰值性能,不需要预热时间。

    AOT编译过程

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

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

    GraalVM多语言架构

    GraalVM支持多语言的原理:将其他语言编译成 .class文件

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

    内存占用对比

    启动时间对比

  • 完善的工具:提供了丰富的开发工具,用于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" : "", "parameterTypes" : [] },            { "name" : "", "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等文件

    4.2 Dubbo支持GraalVM打包成Native Image

    4.3 Quarkus+GraalVM应用上线

来源地址:https://blog.csdn.net/u013794243/article/details/128180933

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

云原生Java框架—Quarkus

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java Kubernetes 与 Java:跨越传统,拥抱云原生架构

在过去的十年中,云原生架构已经成为一种新的软件开发和部署模式,为开发人员带来了许多好处。本文将介绍Java Kubernetes与Java如何结合起来,帮助企业跨越传统,拥抱云原生架构。
Java Kubernetes 与 Java:跨越传统,拥抱云原生架构
2024-02-10

开发php用原生好还是框架好

这篇文章主要介绍“开发php用原生好还是框架好”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“开发php用原生好还是框架好”文章能帮助大家解决问题。原生 PHP当我们说“使用原生 PHP 时”,我们指
2023-07-05

Kubernetes原生边缘计算框架KubeEdge怎么用

本篇文章给大家分享的是有关Kubernetes原生边缘计算框架KubeEdge怎么用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。 KubeEdge成为第一个Kubernete
2023-06-04

java SSM框架 代码生成器 websocket即时通讯 shiro redis 后台框架源码

A代码编辑器,在线模版编辑,仿开发工具编辑器,pdf在线预览,文件转换编码B 集成代码生成器 [正反双向](单表、主表、明细表、树形表,快速开发利器)+快速表单构建器freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面、
2023-06-02

java单元测试JUnit框架原理的示例分析

小编给大家分享一下java单元测试JUnit框架原理的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体如下:1 简介JUnit是一个Java语言的单元测试框架,它由 Kent Beck 和 Erich Gamma
2023-05-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录