2

请问下 Java 如何调用含有第三方依赖的 Python 项目

 8 months ago
source link: https://www.v2ex.com/t/1003544
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Python

请问下 Java 如何调用含有第三方依赖的 Python 项目

  Haku · 13 小时 58 分钟前 · 1346 次点击

公司想搞 AI 相关的,但老企业用的全是 java ,结果就是要用 java 调 python 。

目前只能搞成 java 调 python 打包的 exe 。

也想过用 JNI-CPython-Python 的思路,但是解决不了 python 依赖大量第三方库的问题,没法把 python 代码包括第三方依赖一起给打包成 so 文件。

想问问有没有技术大佬有啥解决思路或者方案。

Nooooobycat

Nooooobycat      13 小时 55 分钟前   ❤️ 1

Python 这边集成一个 web 框架,HTTP 请求进来的时候调用 AI 相关的逻辑。 这样别说用 Java ,bash shell 调用都行
Haku

Haku      13 小时 53 分钟前

@Nooooobycat 这种方案肯定是可行的,但是公司这边这次不让,这次需求上就是不准开端口。
vagusss

vagusss      13 小时 53 分钟前

暴露 http 接口不行么
Haku

Haku      13 小时 52 分钟前

我补充一下,因为上头有要求不开端口(否则会涉及大量的安全策略啥的问题),所以才无奈用的 exe 打包。正常来说跨语言第一反应肯定是走网络通信啥的,
Haku

Haku      13 小时 50 分钟前

@vagusss 上头不让干,大头兵只能无奈执行。
Ayanokouji

Ayanokouji      13 小时 46 分钟前   ❤️ 1

graalvm 试试,虽然我没用过
nagisaushio

nagisaushio      13 小时 46 分钟前 via Android   ❤️ 1

走 unix file socket 也不行么
potatowish

potatowish      13 小时 44 分钟前 via iPhone

python 轮训数据库、队列,看是否有请求过来,有就处理; java 这边需要请求时就写入到数据库、队列,然后轮训获取响应……
Leon6868

Leon6868      13 小时 42 分钟前

@Haku 监听 127.0.0.1 上的端口,不会暴露到网络
Leon6868

Leon6868      13 小时 41 分钟前

可以看看 RPC 相关的内容
NULL2020

NULL2020      13 小时 40 分钟前

关注下,我司最近也要搞类似的方案

JNI-CPython-Python 这个方案大概是怎样,op 能否细说一下
lingeo

lingeo      13 小时 40 分钟前

简单一点就是 web server ,优雅点就 grpc 。
Haku

Haku      13 小时 37 分钟前

@Ayanokouji 我看看,这个看介绍说不定可以哦
Haku

Haku      13 小时 32 分钟前

@NULL2020 如果你的 Python 不涉及第三方库或者你第三方库很简单(没有套娃似的依赖下去),那么你可以把你的 Python 代码通过 c 拓展模块编译成 so 文件,从而可以被 c 调用,而 Java 有 JNI 可以支持你通过 JAVA 来调用 c ,CPython 则负责编写 c 到 python 中间,你要暴露哪些方法出来。这样一来就可以直接由 Java 来调用 python 了。
具体的可以网上搜一下,应该资料也不算少。
而且这种方案一般也比网络方案要快一些,少了很多网络上的开销。但是我找不到第三方依赖的解决办法目前没法用。
nagisaushio

nagisaushio      13 小时 31 分钟前 via Android

楼主先明确,是 不准 java 和 python 分开多个进程,还是只是不准经 tcp 通信?
Haku

Haku      13 小时 30 分钟前

@Leon6868 我们知道不会暴露到网络上,但是领导不知道,也不可能因为我们就改了安全策略。这个不是技术问题。实在是没法解决。┑( ̄Д  ̄)┍
Haku

Haku      13 小时 29 分钟前

@nagisaushio 可以分进程,但是不分更好。网络通信是禁止的。
lsk569937453

lsk569937453      13 小时 28 分钟前

@Haku 笑死,最后 java 调用完 python ,不还是暴漏 http 接口出去,只不过这个 http 是用 java 实现的???
nagisaushio

nagisaushio      13 小时 27 分钟前 via Android   ❤️ 1

@Haku 走 unix socket 也不行吗
lisxour

lisxour      13 小时 27 分钟前

@Haku #17 那就管道呗
Haku

Haku      13 小时 25 分钟前

对了还有个要求,不准直接带来或者改变服务器上的 python 环境。这个也是个坑点,导致我们也没法直接部署 python 代码而使用了 exe 让它可以脱离环境使用。
vicalloy

vicalloy      13 小时 25 分钟前   ❤️ 2

进程间通信总共也就这么几种方法。要不你们用共享内存吧。
lujiaxing

lujiaxing      13 小时 25 分钟前

啥? 这算啥问题, 调 py 脚本难道不就是命令行不就完了么?
Haku

Haku      13 小时 25 分钟前

@lsk569937453 差不多是这样的,很离谱但是就是如此。
yushenglin

yushenglin      13 小时 24 分钟前

有任务队列么,封装一个订阅任务区处理
sujin190

sujin190      13 小时 23 分钟前

@Haku #17 不可以开端口,难道也不可以开 pipe 么?还有 IPC 通信共享内存什么的吧,也没说一定要使用网络才能搞 RPC ,windows 还有更变态的直接用进程 ID 远程写进程内存然后通过内核信号量通知进程执行远程调用的
Haku

Haku      13 小时 22 分钟前

@nagisaushio 这个我不太熟悉,我看看哈
Ayanokouji

Ayanokouji      13 小时 22 分钟前

容器也不行吗
nagisaushio

nagisaushio      13 小时 21 分钟前 via Android

@Haku "不准直接带来 python 环境"什么意思,我把依赖库打包成 zip 算吗?
Haku

Haku      13 小时 20 分钟前

@lujiaxing 部署服务器上没有我们需要的 python 环境,所以跑不动 py 脚本。
@sujin190 pipe 这块不太熟,我看看哈。共享内存已经在考虑了。
Haku

Haku      13 小时 19 分钟前

@nagisaushio 不解压就不算,解压哪怕用了虚拟环境也不行。
Haku

Haku      13 小时 17 分钟前

@yushenglin 这个其实也算可以,不过被使用方否决了,
@Ayanokouji 我记得和容器通信需要搞端口映射吧,因为最终还是要给 java 进程用的,java 进程不是我们写的,所以这个也不让用。
thinkershare

thinkershare      13 小时 13 分钟前   ❤️ 1

每个操作系统都有自己原生的多进程通讯模式,将你的 java/python 搞成多进程架构就行,Java 这边做主进程,负责管理和分发任务给 python 这边。python 是一定需要虚拟机的,不用虚拟机的 python 基本上啥也干不了,没几个库兼容,所以就将环境全部打包进入好了。
Ayanokouji

Ayanokouji      13 小时 13 分钟前   ❤️ 1

@Haku java 不是你们写的,就难办了,graalvm 估计调用方也不会用,还要安装新的 jdk 环境,按这描述只能进程间通信了吧
Ayanokouji

Ayanokouji      13 小时 8 分钟前

@Haku 我说的容器,当成 k8s 里边的 pod 理解,把 java 和 python 放到一个 pod 里边,docker 的话就是一个 compose ,设置下网络策略。在一个 pod 里边用 http 访问。不过按你这描述,容器应该也不会让你们用。
Haku

Haku      13 小时 5 分钟前

@Ayanokouji 理解了。这样确实不行,java 那边不会挪窝的,我们这边最多就是提供点 jar 包做层封装让他们不直接接触 python 这边的东西。
NessajCN

NessajCN      13 小时 0 分钟前

你们编的啥安全策略还禁 localhost 访问的?需要特意改安全策略才允许 localhost 端口访问?
Haku

Haku      12 小时 54 分钟前

@NessajCN 是你可以访问,但是你访问前要给安全过一堆检查,还要写申请,开策略。是“非技术”方面的禁止而非“技术”方面的。但是你不涉及任何网络方面的东西的话,以上冗杂的流程就没了,而目前就是希望别走这个流程。
mightybruce

mightybruce      12 小时 54 分钟前   ❤️ 1

那么多 IPC 的通信方式, 你选一种就行。 简单点就是 unix domain socket, 复杂点搞共享内存、POSIX 消息队列。像这种通信有很多开发库都封装了,比如 zeromq , 自己多试试吧。
hellomsg

hellomsg      12 小时 47 分钟前

给 zfu 外包吗?这么奇葩
NessajCN

NessajCN      12 小时 42 分钟前

@Haku 我觉着要不你还是想办法换个不那么 sb 的领导比较可行
非技术障碍最好也用非技术手段扫除,找找他有没有财务漏洞或者外面是不是养了个三儿啥的
Haku

Haku      12 小时 39 分钟前

@hellomsg 差不多吧哈哈哈哈哈
@NessajCN 不至于不至于,现在朝九晚六舒适的很。而且这个是使用方那边的情况。
ychost

ychost      12 小时 34 分钟前

进程间通信就行了,这样不会暴露网络
yazinnnn0

yazinnnn0      12 小时 29 分钟前

python 监听 domain socket, 开个 web server, 不算网络服务
tomczhen

tomczhen      12 小时 20 分钟前 via Android

典型的没困难创造困难。就算有网友给指方向,非常规方案落地也有一堆坑等着踩。
nomansky

nomansky      12 小时 13 分钟前 via iPhone

@Haku unix socket 哪来的网络通信,都不走网络协议栈。。。
Masoud2023

Masoud2023      12 小时 7 分钟前

直接告诉老板不做 RPC 的话做不了,甭管 unix socket 还是 TCP ,至少你得沾一个,否则甭想。
Alias4ck

Alias4ck      11 小时 48 分钟前

直接用 java 重写你们的的 python 项目吧 我觉得很符合你们的想法 😄
XSDo

XSDo      11 小时 41 分钟前

人为的设置那么多困难,我觉得还可以加更多困难下去,让这个功能实现起来更有挑战
penguinWWY

penguinWWY      11 小时 33 分钟前   ❤️ 1

通过 pybind11 用 c++包一个 exe 出来,静态链接完整的 libpython ,所有依赖打成 zip 包直接通过 c 接口 import 进来
更新依赖的话就重新发个 zip 过去
xuelu520

xuelu520      11 小时 30 分钟前

grpc ,要么内网的 http 接口,再不然就 50 楼说的那种
bringyou

bringyou      11 小时 28 分钟前

实在不行就把 python 都打包到 docker 镜像里,跑镜像就不算改变服务器 python 环境了?
Belmode

Belmode      11 小时 21 分钟前

@Haku "但是你访问前要给安全过一堆检查,还要写申请,开策略" 你这段,我是真的看不懂。跨网络环境,跨机器访问,确实可能需要申请权限,我本机访问本机 http 的 port ,连服务器的外部安全策略都不需要过,还要需要申请什么权限。。。
hertzry

hertzry      10 小时 12 分钟前   ❤️ 1

第三方 package 也都是下载后使用的。譬如 Conda ,你可以找到那个 package 的路径,把它复制到你项目的同一个目录然后 import 。不出意外是可以正常运行的,那么此时相当于第三方 package 是你手动写的,这样打包试一下呢?
nightwitch

nightwitch      10 小时 11 分钟前

走 unix domain socket 呗,进程间通信中比较好用的了。
shared memory 啥的,两边语言都不是 native 语言,操作内存费老大劲
Twelveeee

Twelveeee      9 小时 26 分钟前

@bringyou 合理,如果这也不让,那也不让,起个 docker 最方便
reeco

reeco      8 小时 34 分钟前

python 也是 binding 到 c++,直接用 java binding 到 c++不就好了吗,一个容器搞定。
LoNeZ

LoNeZ      8 小时 23 分钟前

grpc 通信...你这种方式只会增加复杂度...
lujiaxing

lujiaxing      5 小时 12 分钟前

@Haku 那就装一个呀~ 而且现代 Linux 操作系统一般都是自带 Python 环境的... 咋会出现缺 Python 环境的神奇现象

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK