Python中如何优化Django并发下载图片的性能
我想问问我的 django 框架 在服务器 5m 网址 20 并发时获取 500kb,使用 fileresponse 返回图片是,平均获取 10s,这个怎么优化
服务器配置:阿里云 cpu 8 核 内存 32g 网速 5m
Python中如何优化Django并发下载图片的性能
4 回复
这个问题我遇到过。Django处理并发下载图片性能瓶颈主要在I/O等待上,用同步请求会阻塞整个进程。
核心思路是把同步阻塞改成异步非阻塞。我推荐用aiohttp配合asyncio,这样可以在单个线程里并发处理多个下载请求。
import aiohttp
import asyncio
from django.http import JsonResponse
from django.views import View
import os
class AsyncDownloadView(View):
async def get(self, request):
image_urls = request.GET.getlist('urls') # 获取多个图片URL
if not image_urls:
return JsonResponse({'error': 'No URLs provided'}, status=400)
# 并发下载所有图片
images_data = await self.download_images_concurrently(image_urls)
# 这里可以添加保存到本地或数据库的逻辑
# save_images_locally(images_data)
return JsonResponse({
'downloaded_count': len(images_data),
'total_urls': len(image_urls)
})
async def download_images_concurrently(self, urls):
"""并发下载多个图片"""
async with aiohttp.ClientSession() as session:
tasks = [self.fetch_image(session, url) for url in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
# 过滤掉下载失败的(返回异常的)
return [result for result in results if not isinstance(result, Exception)]
async def fetch_image(self, session, url):
"""下载单个图片"""
try:
async with session.get(url, timeout=10) as response:
if response.status == 200:
return {
'url': url,
'data': await response.read(),
'content_type': response.headers.get('Content-Type', '')
}
return None
except Exception as e:
print(f"Failed to download {url}: {e}")
return None
# 在urls.py中配置
# from django.urls import path
# from .views import AsyncDownloadView
#
# urlpatterns = [
# path('download-images/', AsyncDownloadView.as_view(), name='download_images'),
# ]
关键点:
- 用
asyncio.gather()同时发起所有下载请求,而不是一个个顺序下载 aiohttp的异步HTTP客户端不会阻塞事件循环- 设置合理的超时时间避免长时间等待
如果图片数量特别大,可以考虑分批处理,比如每批50个URL,用asyncio.Semaphore控制并发数。
另外,如果下载的图片需要保存,建议用异步文件操作库如aiofiles,避免阻塞在磁盘I/O上。
用异步的方式能让你的Django应用在等待网络响应时继续处理其他请求,显著提升并发性能。
总结:用异步非阻塞代替同步阻塞。
下载图片用 Nginx 等 Web 代理取代,资源安全性通过动态修改文件名实现。
是静态图片么?
理论上说根本不应该让 django 来做提供静态图片的服务。
应该直接用 Nginx 直接来处理静态图片。最好直接用阿里云的 OSS 打开静态网站功能,还能开启 CDN 加速。


