GraalVM 助力 Java 进入函数即服务时代

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: FaaS - 无服务器计算,亦即函数即服务,英文 Fuction as a Service,其目标是希望应用不用一直运行着,只有当有请求来的时候,才快速启动这个应用,然后请求一走就停掉这个应用。换句话说,不让应用在背景程式持续的启动着,而是有需要的时候才开启。

缘起


FaaS - 无服务器计算,亦即函数即服务,英文 Fuction as a Service,其目标是希望应用不用一直运行着,只有当有请求来的时候,才快速启动这个应用,然后请求一走就停掉这个应用。换句话说,不让应用在背景程式持续的启动着,而是有需要的时候才开

启。


这就要求应用要有快速启动,快速停止的能力。

相对庞大的 Jvm 启动时间,加上巨型的 Spring Framework, 很多应用启动动辄分钟级,实现 FaaS 实在是痴心妄想。相比之下,PHP还真是最好的语言,因为 PHP的启动模型本质上就是 FaaS, 你哪哈... 别说了。


话说 Spring 当年就是为了简化 J2EE 的庞杂而出生的,如今也变成了自己讨厌的样子...

软件的问题由软件来解决, Any problem in computer science can be solved with another layer of indirection. 没有什么问题是口罩和护垫解决不了的,如果是,就再加一层。

GraalVM 就是新出现的那一层。

SU_827`1SIQZN[JWGUY{10J.png

从上面看,这一层增加了对多语言的支持,Truffle Framework 支持Ruby, R, Js编译到JVM,再嫁接一下LLVM,那传统的C/C++等也可以统统编译了。话说 C/C++本来就是直接编译成原生的,这回 C -> LLVM -> GrallVM -> 原生, 你品,你细品,究竟折腾个啥。


所以说加层唯一解决不了的问题是层过多的问题:...except for the problem of too many layers of indirection - Kevlin Henney.

从下面看,GraalVM 可以将 .class 编译成原生代码,去掉了包中不使用的代码,大大提高了启动速度,运行速度据称也大大提高。


人生总是不要脸的轮回。当年微软用Visual J++把 Java 编成原生,速度超快,引来的是与Sun的官司战。Sun被Oracle收购,Oracle搞来搞去又走上了这条螺旋下降的道路。

这样,替换VM直接代来了效率提升,带来了和加内存升级CPU一样的效果。

更多原理上的内容可以参考这篇, 写得很详细。只是少分部内容有点过时了。


实操


下载GraalVM

https://www.graalvm.org/downl...

完整地用类用例可以看看这里,有很多:

git clone https://github.com/quarkusio/quarkus-quickstarts.git


Quarkus 框架结合 GraalVM 的各类应用。

下面我们只看几个最简单的 GraalVM 用例.

// HelloWorld.java
public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}
$ native-image HelloWorld
[helloworld:29104]    classlist:     878.53 ms,  0.96 GB
[helloworld:29104]        (cap):   5,001.41 ms,  0.96 GB
[helloworld:29104]        setup:   7,970.43 ms,  0.96 GB
[helloworld:29104]     (clinit):     136.83 ms,  1.20 GB
[helloworld:29104]   (typeflow):   3,437.24 ms,  1.20 GB
[helloworld:29104]    (objects):   3,531.34 ms,  1.20 GB
[helloworld:29104]   (features):     194.35 ms,  1.20 GB
[helloworld:29104]     analysis:   7,426.70 ms,  1.20 GB
[helloworld:29104]     universe:     243.17 ms,  1.20 GB
[helloworld:29104]      (parse):     732.66 ms,  1.67 GB
[helloworld:29104]     (inline):   1,048.13 ms,  1.67 GB
[helloworld:29104]    (compile):   4,809.83 ms,  2.29 GB
[helloworld:29104]      compile:   7,051.94 ms,  2.29 GB
[helloworld:29104]        image:     986.33 ms,  2.29 GB
[helloworld:29104]        write:     252.78 ms,  2.29 GB
[helloworld:29104]      [total]:  24,931.40 ms,  2.29 GB

编译一个helloworld为原生代码需要 24 秒, 同时也需要大量的物理内存,最后一列是内存的使用。

运行,原生:

$ time ./helloworld 
Hello, World!
real    0m0.010s
user    0m0.004s
sys    0m0.003s

比较传统方式:

$ time ./helloworld 
Hello, World!
real    0m0.010s
user    0m0.004s
sys    0m0.003s

这个原生的 helloworld 个头也是惊人的:

$ ll
total 15712
-rw-r--r--   1       427 12  8 00:18 HelloWorld.class
-rw-r--r--   1       116 12  8 00:18 HelloWorld.java
-rwxr-xr-x   1   8032816 12  8 00:19 helloworld

足足 8 Mb.

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
26天前
|
Java Maven Windows
使用Java创建集成JACOB的HTTP服务
本文介绍了如何在Java中创建一个集成JACOB的HTTP服务,使Java应用能够调用Windows的COM组件。文章详细讲解了环境配置、动态加载JACOB DLL、创建HTTP服务器、实现IP白名单及处理HTTP请求的具体步骤,帮助读者实现Java应用与Windows系统的交互。作者拥有23年编程经验,文章来源于稀土掘金。著作权归作者所有,商业转载需授权。
使用Java创建集成JACOB的HTTP服务
|
10天前
|
Java
java基础(11)函数重载以及函数递归求和
Java支持函数重载,即在同一个类中可以声明多个同名方法,只要它们的参数类型和个数不同。函数重载与修饰符、返回值无关,但与参数的类型、个数、顺序有关。此外,文中还展示了如何使用递归方法`sum`来计算两个数之间的和,递归的终止条件是当第一个参数大于第二个参数时。
23 1
java基础(11)函数重载以及函数递归求和
|
8天前
|
JSON Java 数据格式
java调用服务报错400
java调用服务报错400
22 2
|
8天前
|
JSON Java 数据格式
java调用服务报错415 Content type ‘application/octet-stream‘ not supported
java调用服务报错415 Content type ‘application/octet-stream‘ not supported
25 1
|
26天前
|
Java 数据库连接 数据库
Java服务提供接口(SPI)的设计与应用剖析
Java SPI提供了一种优雅的服务扩展和动态加载机制,使得Java应用程序可以轻松地扩展功能和替换组件。通过合理的设计与应用,SPI可以大大增强Java应用的灵活性和可扩展性。
49 18
|
2月前
|
小程序 JavaScript Java
【Java】服务CPU占用率100%,教你用jstack排查定位
本文详细讲解如何使用jstack排查定位CPU高占用问题。首先介绍jstack的基本概念:它是诊断Java应用程序线程问题的工具,能生成线程堆栈快照,帮助找出程序中的瓶颈。接着,文章通过具体步骤演示如何使用`top`命令找到高CPU占用的Java进程及线程,再结合`jstack`命令获取堆栈信息并进行分析,最终定位问题代码。
129 1
【Java】服务CPU占用率100%,教你用jstack排查定位
|
2月前
|
Java 调度 Android开发
Android经典实战之Kotlin的delay函数和Java中的Thread.sleep有什么不同?
本文介绍了 Kotlin 中的 `delay` 函数与 Java 中 `Thread.sleep` 方法的区别。两者均可暂停代码执行,但 `delay` 适用于协程,非阻塞且高效;`Thread.sleep` 则阻塞当前线程。理解这些差异有助于提高程序效率与可读性。
51 1
|
2月前
|
Java 开发者
Java SPI机制大揭秘:动态加载服务提供者,一文让你彻底解锁!
【8月更文挑战第25天】Java SPI(服务提供者接口)是一种强大的扩展机制,允许程序在运行时动态加载服务实现。本文首先介绍SPI的基本原理——定义接口并通过配置文件指定其实现类,随后通过示例演示其实现过程。接着,对比分析了SPI与反射及插件机制的不同之处,强调SPI在灵活性与扩展性方面的优势。最后,基于不同场景推荐合适的选择策略,帮助读者深入理解并有效利用SPI机制。
48 1
|
2月前
|
消息中间件 Java API
解密微服务架构:如何在Java中实现高效的服务通信
微服务架构作为一种现代软件开发模式,通过将应用拆分成多个独立的服务,提升了系统的灵活性和扩展性。然而,实现微服务之间的高效通信仍然是许多开发者面临的挑战。本文将探讨在Java环境中实现微服务架构时,如何使用不同的通信机制来优化服务之间的交互,包括同步和异步通信的方法,以及相关的最佳实践。
|
3月前
|
Java 关系型数据库 MySQL
GraalVM 静态编译下 OTel Java Agent 的自动增强方案与实现
在 2024 OpenTelemetry Community Day 会议中,阿里云可观测工程师张乎兴(望陶)和饶子昊(铖朴)为大家带来了《GraalVM 静态编译下 OTel Java Agent 的自动增强方案与实现》的演讲分享,介绍阿里云在相关领域的探索方案,本文是相关分享对应的中文整理。
235 13
下一篇
无影云桌面