如何扩展Python 服务

Python 正在成为各种应用程序开发人员中越来越流行的选择。然而,与任何语言一样,有效扩展Python 服务可能会带来挑战。本文解释了可用于更好地扩展应用程序的概念。通过了解CPU 密集型任务与 I/O 密集型任务、全局解释器锁 (GIL) 的含义以及线程池和 asyncio 背后的机制,我们可以更好地扩展 Python 应用程序。

CPU 限制与 I/O 限制:基础知识

  • CPU 密集型任务: 这些任务涉及繁重的计算、数据处理和转换,需要大量的 CPU 处理能力。

  • I/O 密集型任务:这些任务通常等待外部资源,例如读取或写入数据库、文件或网络操作。


文章来源地址https://www.toymoban.com/diary/python/477.html

CPU 限制与 I/O 限制

识别您的服务主要受 CPU 限制还是 I/O 限制是有效扩展的基础。

并发与并行:一个简单的类比

想象一下计算机上的多任务处理: 

  • 并发性: 您打开了多个应用程序。即使某一时刻只有一个处于活动状态,您也可以在它们之间快速切换,给人一种它们同时运行的错觉。 

  • 并行性: 多个应用程序真正同时运行,就像在下载文件时在电子表格上运行计算一样。

在单核CPU场景下,并发涉及任务的快速切换,而并行则允许多个任务同时执行。


并发与并行

全局解释器锁:GIL

您可能认为扩展受 CPU 限制的 Python 服务就像添加更多 CPU 能力一样简单。然而,Python 标准实现中的全局解释器锁 (GIL) 使这一点变得复杂。GIL 是一种互斥体,确保一次只有一个线程执行 Python 字节码,即使在多核机器上也是如此。此限制意味着 Python 中受 CPU 限制的任务无法充分利用 GIL 的多线程功能。

扩展解决方案:I/O 限制和 CPU 限制

线程池执行器

此类提供了使用线程异步执行函数的接口。虽然 Python 中的线程非常适合 I/O 密集型任务(因为它们可以在 I/O 操作期间释放 GIL),但由于 GIL,它们对于 CPU 密集型任务的效率较低。

异步

asyncio 适合 I/O 密集型任务,为异步 I/O 操作提供事件驱动框架。它采用单线程模型,在 I/O 等待期间将控制权交还给事件循环以执行其他任务。与线程相比,asyncio 更精简,并且避免了线程上下文切换等开销。

这是一个实际的比较。我们以获取 URL 数据(I/O 绑定)为例,并在没有线程的情况下使用线程池并使用 asyncio 来完成此操作。

import requests
import timeit
from concurrent.futures import ThreadPoolExecutor
import asyncio
URLS = [
    "https://www.example.com",
    "https://www.python.org",
    "https://www.openai.com",
    "https://www.github.com"
] * 50

# 获取URL数据的函数
def fetch_url_data(url):
    response = requests.get(url)
    return response.text

# 1. 顺序
def main_sequential():
    return [fetch_url_data(url) for url in URLS]
  
# 2. 线程池
def main_threadpool():
    with ThreadPoolExecutor(max_workers=4) as executor:
        return list(executor.map(fetch_url_data, URLS))
      
# 3. 带有请求的异步
async def main_asyncio():
    loop = asyncio.get_event_loop()
    futures = [loop.run_in_executor(None, fetch_url_data, url) for url in URLS]
    return await asyncio.gather(*futures)

def run_all_methods_and_time():
    methods = [
        ("顺序", main_sequential),
        ("线程池", main_threadpool),
        ("异步", lambda: asyncio.run(main_asyncio()))
    ]

    for name, method in methods:
        start_time = timeit.default_timer()
        method()
        elapsed_time = timeit.default_timer() - start_time
        print(f"{name} 执行时间: {elapsed_time:.4f} seconds")

if __name__ == "__main__":
    run_all_methods_and_time()

结果

顺序执行时间: 37.9845 seconds 
线程池执行时间: 13.5944 seconds 
异步执行时间: 3.4348 seconds


结果表明,asyncio 对于 I/O 密集型任务非常高效,因为它最小化了开销并且没有数据同步要求(如多线程所示)。

对于 CPU 密集型任务,请考虑:

  • 多处理:进程不共享 GIL,使得这种方法适合 CPU 密集型任务。但是,请确保生成进程和进程间通信的开销不会削弱性能优势。

  • PyPy:带有即时 (JIT) 编译器的替代 Python 解释器。PyPy 可以提高性能,特别是对于 CPU 密集型任务。

在这里,我们有一个正则表达式匹配的示例(CPU 限制)。我们在没有任何优化的情况下使用多处理来实现它。

import re
import timeit
from multiprocessing import Pool
import random
import string

# 非重复字符的复杂正则表达式模式。
PATTERN_REGEX = r"(?:(\w)(?!.*\1)){10}"

def find_pattern(s):
    """Search for the pattern in a given string and return it, or None if not found."""
    match = re.search(PATTERN_REGEX, s)
    return match.group(0) if match else None

# 生成随机字符串的数据集
data = [''.join(random.choices(string.ascii_letters + string.digits, k=1000)) for _ in range(1000)]

def concurrent_execution():
    with Pool(processes=4) as pool:
        results = pool.map(find_pattern, data)

def sequential_execution():
    results = [find_pattern(s) for s in data]

if __name__ == "__main__":
    # Timing both methods
    concurrent_time = timeit.timeit(concurrent_execution, number=10)
    sequential_time = timeit.timeit(sequential_execution, number=10)

    print(f"并发执行时间(多处理): {concurrent_time:.4f} seconds")
    print(f"顺序执行时间: {sequential_time:.4f} seconds")

结果

并发执行时间(多处理): 8.4240 seconds 
顺序执行时间:12.8772 seconds


显然,多处理优于顺序执行。通过实际用例,结果将更加明显。

小结

扩展 Python 服务取决于识别任务的性质(CPU 密集型或 I/O 密集型)并选择适当的工具和策略。对于 I/O 密集型服务,请考虑使用线程池执行程序或asyncio,而对于 CPU 密集型服务,请考虑利用多处理。


到此这篇关于如何扩展Python 服务的文章就介绍到这了,更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

原文地址:https://www.toymoban.com/diary/python/477.html

如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用
使用ReactJS从零开始创建Web的ChatGPT应用程序
上一篇 2023年10月28日 00:08
大容量分布式数据处理中倾斜数据集的处理方法
下一篇 2023年10月28日 00:46

相关文章

  • 阿里云服务器的扩展性如何?是否支持弹性扩容和自动负载均衡?

    阿里云服务器的扩展性如何?是否支持弹性扩容和自动负载均衡? 阿里云服务器的扩展性特点 阿里云服务器(ECS)在扩展性方面具有优势,能够满足用户不断变化的业务需求。以下我们将详细介绍阿里云服务器的扩展性特点。 弹性伸缩 * 阿里云服务器支持根据业务需求进行

    2024年02月09日
    浏览(42)
  • 【小沐学Python】Python实现Web服务器(Flask框架扩展:Flask-Admin)

    flask作为一个微框架,Flask 允许您以很少的开销构建 Web 服务。 它为您(设计师)提供了自由,以适合您的方式实施您的项目 特定应用。 一个最小的 Flask 应用如下: Flask-Admin是一个batteries-included,易于使用的Flask扩展,可让您 向 Flask 应用程序添加管理界面。它的灵感来自 d

    2024年02月02日
    浏览(89)
  • 如何利用容器与中间件实现微服务架构下的高可用性和弹性扩展

    本文分享自天翼云开发者社区《如何利用容器与中间件实现微服务架构下的高可用性和弹性扩展》,作者:c****w 在当今的互联网时代,微服务架构已经成为许多企业选择的架构模式,它能够提高系统的灵活性、可维护性和可扩展性。然而,微服务架构下的高可用性和弹性扩展

    2024年01月19日
    浏览(66)
  • 使用vscode Remote SSH连接远端服务器安装python扩展后仍无法运行python文件

    !!!!最先说明,连接远端服务器的时候不要挂VPN,连接外网!!! 如果挂了梯子,大概率都会安装不上/无法使用激活扩展!!!! 所以执行以下操作之前,先把梯子给退了。 第一步,检查你的远端服务器上是否有python。  如果没有,请安装python环境。网上教程很多,就

    2024年04月23日
    浏览(53)
  • 解决python扩展在连接远程服务器时无法使用: 此扩展在此工作区中被禁用,因为其被定义为在远程扩展主机中运行。请在 ‘SSH: xxxxx‘ 中安装扩展以进行启用

    问题如题,解决后的效果如下: 出问题时,在上图中会出现一行小字“此扩展在此工作区中被禁用,因为其被定义为在远程扩展主机中运行。请在 ‘SSH: xxxxx’ 中安装扩展以进行启用”。导致你ctrl点函数不会进行跳转,也就是Python扩展的功能完全没用实现,非常不方便。 具

    2024年02月07日
    浏览(313)
  • 由于数字化转型对集成和扩展性的要求,定制化需求难以满足,百数低代码服务商该如何破局?

    当政策、技术环境的日益成熟,数字化转型逐步成为企业发展的必选项,企业数字化转型不再是一道选择题,而是决定其生存发展的必由之路。通过数字化转型升级生产方式、管理模式和组织形式,激发内生动力,成为企业顺应时代变化,实现高质量发展的必然选择。 一般来

    2024年02月07日
    浏览(51)
  • 【深入了解pytorch】PyTorch扩展:如何使用PyTorch的扩展功能

    PyTorch作为一个开源的深度学习框架,在研究和应用领域广受欢迎。其灵活性和可扩展性使得用户能够根据自己的需求进行定制化操作,包括自定义损失函数、数据加载器和优化器。本篇博文将深入探讨如何利用PyTorch的扩展功能,为深度学习任务定制化开发工具。 损失函数是

    2024年02月12日
    浏览(48)
  • 如何在服务器上运行 Python 程序

    大家好,我是强哥。 今天给大家分享一个小的知识点, 如何在服务器上运行 Python 程序 。 我的服务器系统是 CentOS 7.9 ,这也是最常用的服务器系统之一。 我将以此为例,给大家介绍一个零基础也可以轻松上手的,在服务器上运行 Python 程序的方法。 安装好宝塔面板以后,主

    2024年01月23日
    浏览(39)
  • BurpSuite扩展--python扩展运行环境配置

    Burp扩展可以用Java,Python或Ruby编写。Java扩展可以直接在Burp中运行,而无需任何其他配置。在安装以Python或Ruby编写的扩展之前,您需要下载Jython或JRuby,它们是用Java实现的那些语言的解释器。如果要安装Python扩展,则必须下载Jython的独立版本   Jython运行环境 https://www.jython.

    2023年04月09日
    浏览(43)
  • 【经验分享】如何为visio扩展云服务图标

    各个云厂商都会为自己的服务提供通用可缩放矢量图形 (SVG) 图标,以便用户为自己的软件绘制架构图,例如Microsoft 为Visio 提供 Azure 服务的图标。文本在这里简单整理了几个关于云服务的图标 Azure-Design 提供了大量并完整的azure的一些图标 AWS-Architecture-Icons 提供了一些关于AW

    2024年02月06日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包