Java的Sping Boot vs Python的FastApi:螺纹

z4iuyo4d  于 2023-05-21  发布在  Java
关注(0)|答案(3)|浏览(710)

我是一名Java Sping Boot 开发人员,我开发3层CRUD应用程序。我和一个看起来对这个问题很了解的人谈过,但我没有得到他的联系方式。他提倡Python的FastApi,因为它的水平扩展比Sping Boot 更好。他提到的原因之一是FastApi是单线程的。当线程遇到数据库查找(或其他可以异步完成的工作)时,它会选择其他工作,以便在数据库结果输入后返回到当前工作。在Java中,当有许多请求挂起时,线程池可能会耗尽。
我不明白这个道理100%。让我来唱反调吧。当Python程序遇到异步调用时,它必须以某种方式将程序指针存储在某个地方,以便记住稍后需要继续的地方。我知道存储程序指针的地方根本不是线程,但我必须给予它起个名字,所以我们称之为“逻辑线程”。在Python中,可以有许多逻辑线程在等待。在Java中,你可以有一个线程池,里面有许多等待的真实的线程。对我来说,唯一的区别似乎是Java的线程是在操作系统级别管理的,而Python的“逻辑线程”是由Python或FastApi管理的。为什么在线程池中等待的真实的线程比等待的逻辑线程要昂贵得多?如果我的大多数线程都在等待,为什么我不能增加线程池的大小以避免耗尽?

exdqitrt

exdqitrt1#

问题中的Java线程问题由Loom项目解决,该项目计划包含在未来的JDK中。这里很好地解释了https://www.baeldung.com/openjdk-project-loom
目前,Java依赖于OS实现[线程的延续]和[线程的调度]。
现在,为了挂起continuation,需要存储整个调用堆栈。类似地,在恢复时检索调用堆栈。由于延续的OS实现包括本机调用堆栈沿着Java的调用堆栈,因此它导致了沉重的占用空间。
不过,一个更大的问题是操作系统调度程序的使用。由于调度程序在内核模式下运行,因此线程之间没有区别。它以相同的方式处理每个CPU请求。(...)例如,考虑一个应用程序线程,它对请求执行一些操作,然后将数据传递给另一个线程进行进一步处理。在这里,最好在同一CPU上调度这两个线程。但是由于[OS]调度程序对于请求CPU的线程是不可知的,因此这是不可能保证的。
这个问题实际上可以归结为Why are OS threads considered expensive?

h9vpoimq

h9vpoimq2#

这在很大程度上取决于你的线程在做什么。假设您的请求正在调用某个外部端点。大多数时候,你的java线程(很重)什么都不做。有问题吗?取决于。在java生态系统中,线程不是动态创建的,这个问题在任何像样的框架中都可以通过线程池来解决。
但线程堆栈大小仍然占用内存。如果你在一个线程池中有1000个线程(或者1000个并发请求)在等待IO操作,那么你的内存可能很容易超过1GB。
对于这种特定的场景,一些async / await抽象可以更好地利用内存。是否所有任务都能更快地执行是另一回事,取决于许多因素。
所以你真的需要更深入,你说的是什么规模?内存-或所有操作的执行速度(通常也涉及一些CPU)。
java不可忽视的优点是,线程处理的请求可以并行运行,并利用许多处理器,而在python中,这是根本不可能的。
FastAPI及其异步等待模型易于使用,将开发人员从线程模型和考虑并发性中分离出来。不幸的是,这也意味着更小的控制,以防万一这是必要的。
在python中调用async方法并不能使代码执行更快。最后,在引擎盖下,有一个事件循环只在一个CPU上运行。
根据使用情况,它足够好和有效,或者恰恰相反。
通常来自Python生态系统的人都在大肆宣传沉重的Java,只是用它更快/更轻的论点,而没有看到其他的缺点。
这里还有一个链接,可以通过几个框架(在Web / REST场景中)之间的典型WebApp性能比较来逗你开心
https://www.travisluong.com/fastapi-vs-fastify-vs-spring-boot-vs-gin-benchmark/

nzk0hqpo

nzk0hqpo3#

FastAPI是一个快速的框架,您可以在其中快速(轻松)创建API后端。老实说,如果你是一个Java开发人员,我会推荐Quarkus或其他东西来构建REST API,而不是FastAPI。FastAPI是一个很棒的工具,如果你已经在Python生态系统中,它绝对是一个很棒的工具。
当它涉及到多线程时; Java是“真实的的”多线程,而Python则不是。Java线程将并发运行;可以并且将同时执行两个任务。在Python中,在一个Python进程中,这(几乎)是不可能的。这是因为GIL(谷歌一下,有很多关于它如何工作的东西)。结果是;即使你在Python中使用“真实的的”线程,代码仍然不是并发执行的,而是串行执行的,其中解释器(与Java有很大的区别)不断地从一个调用堆栈跳到另一个调用堆栈。
至于你所说的“逻辑线程”,我想你指的是Python的异步能力。这基本上和使用线程是一样的(不是真的,但是在抽象层面上它们非常相似);任务不是并发运行的。只有一个线程在任务之间不断切换。任务将把控制权交还给事件循环(协调任务并决定以何种顺序执行什么的对象),并进一步执行另一个任务,直到该任务产生控制权,等等。它基本上与Python中的线程执行模式相同。
在我看来,将Python框架与Java框架进行比较是很奇怪的。它们既有用又酷,但不是真正的竞争对手。

相关问题