在很多场景下,我们都有从java调用脚本的功能,常用的有groovy脚本,pyhon脚本和js等。在
上篇
中,列举了java调用pyhton脚本的几种方案,并最终选取了JEP的方式,但是随着业务的提升,JEP由于GIL锁的问题,每次只能执行一次脚本,并发高的情况下,由于资源竞争,JEP会变得非常慢,于是需要新的方案来解决这个问题。
通过查阅资料,找到了一种可行的方案,首先我们了解下什么是
GraalVM
GraalVM 是一款基于 Java 虚拟机 (JVM) 的新型全栈虚拟机,由 Oracle 公司开发和维护。GraalVM 除了支持 Java 语言之外,还支持多种编程语言,如 JavaScript、Python、Ruby、R 等。
GraalVM 的主要特点包括:
-
高性能:GraalVM 基于 JIT (Just-in-time) 编译技术,在运行时动态生成本地代码,可以显著提高程序的性能。
-
多语言支持:GraalVM 支持多种编程语言,并可以在不同的语言之间进行互操作。
-
低内存占用:GraalVM 使用了一种名为 GraalVM Native Image 的技术,可以将应用程序编译成本地可执行文件,从而减少内存占用和启动时间。
-
可扩展性:GraalVM 提供了多种插件和扩展点,可以方便地扩展虚拟机的功能和性能。
-
GraalVM 还提供了多种工具和库,如 GraalVM Compiler、GraalVM Truffle、GraalVM Polyglot 等,可以帮助开发人员更好地使用和优化 GraalVM。
GraalPython
是基于 GraalVM 平台的 Python 解释器,由 Oracle 公司和社区开发维护。它支持 Python 3.7 语言规范,并且与 CPython 兼容,可以运行大部分的 Python 代码。
GraalPython 的主要特点包括:
-
高性能:GraalPython 使用了 GraalVM 平台的 JIT 编译器技术,可以将 Python 代码编译成本地代码,提高程序的执行效率。
-
多语言互操作:GraalPython 支持 GraalVM 平台的 Polyglot API,可以与其他编程语言进行互操作。
-
执行安全:GraalPython 支持沙箱机制,可以限制 Python 代码的访问权限,保证执行安全。
-
可扩展性:GraalPython 提供了多种扩展点和插件机制,可以方便地扩展其功能和性能。
GraalPython 与 CPython 之间的差异主要在于其内部实现机制。GraalPython 使用了 GraalVM 平台的 Truffle 框架,将 Python 代码转换为 AST (抽象语法树) 并进行优化,然后使用 JIT 编译器生成本地代码。相比之下,CPython 是使用 C 语言实现的,其执行速度较慢,但兼容性更好,可以运行大部分的 Python 代码。
需要使用GraalPython,我们首先要搭建GraalPython环境
安装 GraalVM:下载 GraalVM 安装包并解压缩,然后将其添加到环境变量中。可以参考官方文档:https://www.graalvm.org/docs/getting-started/linux/。
安装 GraalPython:打开终端,执行以下命令安装 GraalPython:
gu install python
该命令会自动安装最新版本的 GraalPython。
验证 GraalPython:执行以下命令验证 GraalPython 是否安装成功:
python --version
如果输出 Python 的版本信息,则说明 GraalPython 安装成功。
使用 GraalPython:在终端中执行以下命令启动 GraalPython 解释器:
graalpython
然后就可以在 GraalPython 环境中运行 Python 代码了。
安装好GraalPython后,我们需要构建venv环境, venv是 Python 3 自带的一个标准库,它可以帮助用户创建虚拟环境,使得不同的项目之间的依赖关系和库版本隔离开来,从而避免了不同项目之间的库冲突和版本不兼容等问题。
使用 venv 创建虚拟环境非常简单,可以按照以下步骤操作:
打开终端,进入项目的根目录,执行以下命令创建虚拟环境:
graalpy -m venv /home/appuser/venv
上述命令将在当前目录下创建名为 myenv 的虚拟环境。
激活虚拟环境:执行以下命令激活虚拟环境:
source /home/appuser/venv/bin/activate
执行上述命令后,终端的提示符会变为 (myenv),表示虚拟环境已经激活。
![在这里插入图片描述](https://img-blog.csdnimg.cn/5c7dc6883d214781b29f1563f19dd2c1.png)
在虚拟环境中安装依赖:执行以下命令安装需要的依赖:
pip install package_name
在虚拟环境中安装的依赖包仅对当前项目有效,不会影响系统中的其他项目。
退出虚拟环境:执行以下命令退出虚拟环境:
deactivate
执行上述命令后,终端的提示符会恢复为原来的样子。
需要注意的是,每次进入项目的开发环境时,都需要激活虚拟环境,否则无法使用虚拟环境中的依赖和库。
环境准备好后,我们就可以使用java环境调用python脚本。
- 首先导入sdk包
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>22.3.1</version>
</dependency>
- 然后编写代码
private static final String PYTHON = "python";
private static final String PYTHON_PYTHON_PATH = "python.PythonPath";
private static final String PYTHON_EXECUTABLE = "python.Executable";
private static final String PYTHON_FORCE_IMPORT_SITE = "python.ForceImportSite";
private static Context createContext(String modulePath){
Engine engine = Engine.create();
Context context = Context.newBuilder(PYTHON).allowAllAccess(true).engine(engine)
.option(PYTHON_FORCE_IMPORT_SITE, "true")
.option(PYTHON_PYTHON_PATH, modulePath)
.option(PYTHON_EXECUTABLE, customizeConfig.getPythonExecutable())
.build();
return context;
public static void main(String[] args) {
Context context = createContext();
Value bindings = context.getBindings(PYTHON);
bindings.putMember("a", 1);
bindings.putMember("b", 2);
int i = context.eval(PYTHON, "a+b").asInt();
System.out.println(i);
讲解下关键参数:
- python.PythonPath 导入外部py文件目录的地址,比如a/a.py
- python.Executable隔离环境的地址,上文中的/home/appuser/venv
- python.ForceImportSite 强制开启site,这个功能主要是需要使用第三方库,如requests,则需要在这配置参数,开启sitespackge目录,当然,我们也可以通过脚本中运行”import site“开启。
至此我们通过graalpy实现了java中调用python脚本,在测试过程中,当我们不适用三方库的时候,性能比较客观,但是当我们使用ForceImportSite后性能有显著下降,当然整体比JEP好很多。
在预言过程中发现每次创建上下文Context非常耗时,一次执行就需要4s多,后来才支持因为cpu内核导致的,我使用的环境是mac m1,下载使用的事GraalVM(amd64),而m1以上的需要下载GraalVM(aarch64)版本,更改后瞬间将速度提升到毫秒级别。
当然GraalVM针对python的试验阶段,一旦能适用,几乎可以毫无成本的引入js脚本的支持,平台引入这个工具具有很高的扩展性
另外,目前对于第三方库python库的支持不是特别兼容,需要继续摸索
官方支持的兼容包如下:
Cython
Keras_preprocessing
Markdown
Pillow
PyYAML
Werkzeug
absl_py
astor
atomicwrites
attrs
cassowary
certifi
chardet
cppy
cycler
dateutil
gast
h5py
hypothesis
idna
joblib
kiwisolver
lightfm
matplotlib
mock
more_itertools
numpy
packaging
pandas
pkgconfig
pluggy
protobuf
py
pybind11
pyparsing
pytest
pytest_parallel
python_dateutil
pythran
pytz
requests
scikit_learn
scipy
setuptools
setuptools_scm
six
sortedcontainers
threadpoolctl
tox
urllib3
wcwidth
wheel
zipp
是否使用GraalVM举要根据自己具体的使用场景去评估,如果只是简单的脚本调用就非常适合,性能客观,但是存在大量的第三方库和自定义库性能就会收到影响,同事需要考虑兼容问题。
*如果您想支持这些教程,可以向我的捐款
GraalVM Python
这是一个演示项目,说明如何使用GraalVM和Quarkus框架在Java应用程序中运行其他编程语言,例如Javascript和Python。
准备当地环境
您必须在Ubuntu OS上运行。
下载并配置GraalVM。
将GRAALVM_HOME设置为您提取GraalVM tar文件的位置。
将JAVA_HOME设置为GRAALVM_HOME。
将JAVA_HOME添加到PATH变量。
在GraalVM / bin文件夹中导航。
安装本机映像。
./gu install native-image
在GraalVM中安装Python。
./gu install python
// check the available packages
./graalpython -m ginstall in
Python的GraalVM实现这是Python的早期实验实现。
一个主要目标是支持SciPy及其组成库。
该Python实现目前旨在与Python的Pyth GraalVM实现兼容。这是Python的早期实验实现。
一个主要目标是支持SciPy及其组成库。
目前,此Python实现旨在与Python 3.7兼容,但是距此还有很长的路要走,任何需要任何软件包的Python程序很可能会遇到不受支持的情况。
至此,Python实现可供实验和好奇的最终用户使用。
Python的GraalVM实现
这是Python的早期实验实现。 一个主要目标是支持SciPy及其组成库。 GraalPython通常可以比CPython更快地执行纯Python代码(但涉及C扩展时则不能)。 GraalPython当前的目标是与Python 3.8兼容,但是距离那里还有很长的路要走,使用标准库模块或外部软件包的更多功能的任何Python程序很可能会遇到不受支持的情况。 至此,Python实现已可供实验和好奇的最终用户使用。
尝试GraalPython的最简单选择是Python版本管理器 。 它使您可以轻松安装不同的GraalPython版本。 例如,要获取版本20.2,只需运行pyenv install graalpython-20.2 。
要在完整的GraalVM上尝试GraalPython,包括对Java嵌入的支持以及与其他语言的互操作,可以使用的捆绑发
文章目录关于 GraalVM安装GraalVM Python使用 ginstall 安装第三方包graalpython 交互模式下执行 python 代码
关于 GraalVM
GraalVM : a high-performance JDK distribution
It is designed to accelerate the execution of applications written in Java and other JVM languages while also providing
前言2018年4月,Oracle Labs新公开了一项黑科技:Graal VM。这是一个在HotSpot虚拟机基础上增强而成的跨语言全栈虚拟机,可以作为“任何语言”的运行平台使用。现在网络上关于 Graal VM 的相关资料并不多,还是要看官方文档。本文旨在简要介绍:什么是 Graal VM?Graal VM 有什么好处?Graal VM 有什么缺点?Graal VM 的工作原理是什么?...
最近碰到几个人问,如何实现 java 调用他们写好的 Python 应用(模型),这里我就把几种常见的办法做下汇总整理。喜欢本文记得收藏、点赞。本文由技术群粉丝分享,项目源码、数据、技术交流提升,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友如使用 java 的 API,
2. 通过 REST API
REST 是表现层状态转换(英语:Representational State Transfer)的英文缩写,是 Roy Thomas Fieldi
GraalVM是开发人员编写和执行Java代码的工具。具体来说,GraalVM是由Oracle创建的Java虚拟机(JVM)和Java开发工具包(JDK)。它是一个高性能的运行时,可以提高应用程序的性能和效率。GraalVM的目标包括:编写一个更快、更易于维护的编译器,提高在JVM上运行的语言的性能,减少应用程序启动时间,将多语言支持集成到Java生态系统中,以及为此提供一组编程工具。GraalVM向JDK添加了一个优化编译器,它为各种语言提供性能优化,并为多语言应用程序提供互操作性。...
构建在GraalVM之上的一个Python 3实现
Python 的 GraalVM 实现 这是 Python 的早期实验实现。
一个主要目标是支持 SciPy 及其组成库。
这个 Python 实现目前的目标是与 Python 3.7 兼容,但距离那里还有很长的路要走,而且很可能任何需要任何包的 Python 程序都会遇到不受支持的东西。
此时,Python 实现可供实验和好奇的最终用户使用。
试用 要试用,您可以使用 www.graalvm.org 中的捆绑版本。
有关更多信息和您可以使用它做什么的一些示例,请查看参考资料。
创建虚拟环境 使用 Python 的 GraalVM 实现的最佳方式是脱离虚拟环境。
这将生成包装器脚本并使实现可从 shell 作为标准 Python 解释器使用。
为此,请在项目目录中执行以下操作: Build GraalPython: mx build 创建 venv: mx python -m venv
在 shell 会话调用中激活环境: source
/bin/activate 在 venv 中可以使用多个可执行文件,例如 py
最近碰到几个人问,如何实现 java 调用他们写好的 Python 应用(模型),这里我就把几种常见的办法做下汇总整理。喜欢本文记得收藏、关注、点赞。
【注】文末提供技术交流群
李宏毅《机器学习》国语课程(2022)来了
有人把吴恩达老师的机器学习和深度学习做成了中文版
上瘾了,最近又给公司撸了一个可视化大屏(附源码)
如此优雅,4款 Python 自动数据分析神器真香啊
梳理半月有余,精心准备了17张知识思维导图,这次要讲清统计学
年终汇总:20份可视化大屏模板,直接套用
GraalVM有许多不同的组件,如果你只是听说过它或有些简单的了解,肯定无法一窥全豹。本文将列举下GraalVM的几大常用功能,看看它们都能做些什么。
高性能的现代Java
占用资源少,启动速度快
JavaScript, Java, Ruby以及R混合编程
在JVM上运行原生语言
跨语言工具
JVM应用扩展
原生应用扩展
本地Java库
数据库支持多语言
创建自己的语言
本文将要介绍的内容在Gra...
前阵子,Oracle 发布了一个黑科技 "GraalVM",号称是一个全新的通用全栈虚拟机,并具有高性能、跨语言交互等逆天特性,真有这么神奇?
GraalVM 简介
GraalVM 是一个跨语言的通用虚拟机,不仅支持了 Java、Scala、Groovy、Kotlin 等基于 JVM 的语言,以及 C、C++...