python - 管理数千个套接字客户端连接:多线程或异步(带队列)
问题描述
我实际上阅读/观看了很多博客、tuto、prog 网站、视频等……我在多处理、多线程、异步、队列、并发、并行等方面学到了很多东西……
但是我找不到什么是编写我真正想到并刚刚开始编写的程序的最佳方法。
这个想法很简单:
- 一台只有一个 vCPU 的服务器 (VPS),其中包含根据客户端顺序管理多个文件夹的服务器脚本。
- 至少一千个向服务器提供命令和文件的客户端。
- 一个客户端可以管理多个文件夹,每个文件夹可以被多个客户端管理。
我的问题是,如何处理每个客户端套接字连接,知道大多数时候连接上不会有任何活动,除了定期检查客户端是否有要执行的任务。
我知道多线程是一个不错的选择,但创建数千个线程(与队列相关联)对我来说有点夸张。
而且我知道 Python Asyncio 是在单线程上实现良好性能并发的一个很好的选择(而且uvloop可以更快地进行异步)。
服务器端程序基本上只会对 PostgreSQL 数据库的 MySQL 执行操作并删除、重命名、下载、上传文件/目录。并且可能发送少量邮件并生成 PDF 活动报告。
抱歉,如果解释得不好,但这个想法还没有真正完成。而且我是法国人,所以我的“非谷歌翻译”英语质量可能很差。
亲切地
解决方案
通常,您应该避免自己创建线程,因为如果创建太多线程可能会导致线程爆炸和执行缓慢。
线程池是解决您的问题的好方法,它创建一个固定的线程池,然后您向它提交工作。
一个(非常)人为的concurrent.futures
Python 库示例:
from concurrent.futures import ThreadPoolExecutor, as_completed
with ThreadPoolExecutor as e:
while True:
# The polled client requests
new_client_requests = ...
# Submit requests for concurrent execution in the thread pool
futures = [e.submit(do_request, r) for r in new_client_requests]
for response in as_completed(futures):
# Send back the response to the client...
您也可以在.map()
使用不同参数执行一项作业时使用该方法。
这种方法的缺点是太多的客户端请求可能会使您的程序崩溃,因为它们会堆积起来。但是,您应该使用更专业的库来管理和平衡负载。
推荐阅读
- redis - celery + redis 任务分配不均是否有原因?
- guidewire - 如何使用 Guidewire 中的反射控制 PCF 的可见性
- android - 自定义 ConstraintLayout 属性
- swift - SwiftUI 中的 NSItemProvider loadObject 拖放
- flutter - Flutter web,图标呈现错误的图标
- excel - 使用正在复制到电子邮件的 VBA 格式化表格
- html - 为什么在 django 中尝试使用 for 循环进行迭代时 html 会消失
- python - Python Parse tree IndexError:字符串索引超出范围
- c# - C# 到 VB 转换后表单加载事件未触发
- java - 更改名称模式后未生成 Log4j2 日志文件