import concurrent.futures
import time
# 定义耗时任务
def time_consuming_task(task_id,a,b):
print(f'Starting task {task_id}--{[a,b]}')
time.sleep(1) # 模拟耗时任务
print(f'Finished task {task_id}--{[a,b]}')
return f'ff=={task_id}'
if __name__ == '__main__':
# 创建线程池
max_workers = 20
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
# 提交任务到线程池
task_ids = range(1, 10001) # 假设有1万个任务
futures = [executor.submit(time_consuming_task, task_id,1111,2222) for task_id in task_ids]
# 等待所有任务完成
for future in concurrent.futures.as_completed(futures):
try:
a=future.result() # 获取任务结果
print(f'>>>>>{a}')
except Exception as e:
print(f'Error occurred: {e}')
废话不多说,代码如上。倒序讲下问题由来
问题
后台服务S支持批量任务提交
每个任务都是异步请求服务B的api,单个估计半小时左右
后台服务S会间歇性对每个任务从服务B拉取结果,然后存入DB,一个任务结束。
方案一
服务S接收到1万个任务,发起一万个子线程。。。问题来了:
- 数据库连接池耗尽
- 方案:调大数据库连接池
- Mysql配置修改
- max_connections = 10000
- sqlalchemy
-
pool_size=3000, max_overflow=7000
-
- Mysql配置修改
- 方案:调大数据库连接池
- sqlalchemy经常性连接断开
- 方案: 开启预检
- pool_pre_ping=True
- 方案: 开启预检
- 服务B经常性请求超时
- 猜测是高并发请求导致的
- 自身有队列,并发任务数最多为100
任务失败率太高,资源消耗过重
方案二
服务S接收到1万个任务,先入库,然后开启大小为100的线程池,服务S单任务并发量为100,这样完美和服务B并发数匹配,再也不怕海量任务啦。