使用Django为许多动态生成的图像提供服务

时间:2012-09-12 11:59:18

标签: python django apache comet wsgi

与空间图像数据的平铺服务器类似,我想在基于Django的Web应用程序中查看许多动态生成的图像(合并图像,颜色变化等)。由于一个客户端可以在短时间内轻松请求多个(> 100个)图像,因此很容易将Web服务器(Apache + mod_wsgi)关闭。

因此,我正在寻找替代方法。由于我们已经使用了Celery,因此异步执行此图像处理并将生成的数据推送到客户端可能是个好主意。为了开始这一点,我将WSGI服务器切换为gevent,Apache用作代理。但是,我还没有设法推动推动工作,但我不确定这是否是正确的方向。基于此,我有三个问题:

  1. 您是否认为这(Celery,gevent,Socket.IO)是一种明智的方式,允许许多客户端使用该应用程序而无需关闭Web服务器?你看到了替代品吗?

  2. 如果我将图像处理交给Celery并在完成后将图像数据推送到浏览器,那么连接将不会通过Apache,是吗?

  3. 如果使用某种推送方式,最好是为每张图片使用一个连接或一个连接(并在完成后关闭它)?

  4. 背景:

    我正在处理的Django应用程序允许用户显示非常大的图像。这是通过在之前平铺大图像并且仅向用户显示网格中的当前相关图块来完成的。据我所知,这是在地图和空间图像数据领域(例如OpenStreetMap)中提供数据的标准方法。但与地图数据不同,我们在Z中也有许多切片,用户可以滚动(生物图像)。

    当静态处理切片时,所有这些都可以正常工作。现在我添加了选项来动态生成这些图块 - 合并不同的图像,校正颜色,....这是有效的,但是对于Web服务器来说是一些重负荷,因为一个图像需要大约0.1秒才能生成。目前我们将Apache与mod_wsgi(WSGIRestrictedEmbedded On)一起使用,很容易将服务器关闭。只是浏览图像堆栈将导致挂起的Web服务器。我已经尝试调整MaxClients等,并关闭了KeepAlive。我还为mod_wsgi尝试了不同的线程/进程组合。但是,没有任何帮助足以允许多个用户使用。因此,我认为Comet / WebSocket方式可以在这里提供帮助。

3 个答案:

答案 0 :(得分:1)

  

当静态处理切片时,所有这些都可以正常工作。现在我补充道   即时生成这些图块的选项 - 不同的图像   合并,颜色校正,.......这是有效的,但是有一些重负荷   Web服务器作为一个图像需要大约0.1秒生成。

您需要一个负载均衡器,将图像请求发送到前端服务器(例如NginX),该服务器将根据需要多路复用(并缓存!)多个请求,前提是您提供足够的后端服务器来完成繁重的工作。

这看起来像是亚马逊分布式计算的经典案例:您可以将磁贴存储在S3存储(或者通过EBS的NFS)中。所有图像处理服务器都从单个图像存储库中获取数据。

开始时,您可以在同一台计算机上同时拥有Web应用程序和图像处理服务器的一个实例。但基本上你的流程是三个:

  • 计算图片网址的网络服务(您需要某种方式将操作编码为网址中的参数,否则您将不得不使用Cookie和会话存储,这更ickier)
  • 接收“图像公式”并提供JPEG图块的图像服务器
  • 允许访问大图像或单个原始图块的文件服务器

我曾在几个这样的架构中工作,其中我们的图像层存储在单个图像文件中(例如,五个缩放级别,每个十五个通道从FIR到UV,总共75个“图像”,最多100K像素)一方,客户可以要求'缩放级别2,红色通道加上UV-1通道和绿色之间的差异的两倍,从X = 157,Y = 195到X = 167,Y = 205')。

答案 1 :(得分:0)

如果您只需要一个用户将Web服务器关闭,则问题不在于apache或mod_wsgi。

首先,您应该优化您的平铺例程,并检查您是否真的只提供用户实际看到的数据。

之后,更快的CPU,更多内存,ssd和积极的缓存将为您带来更多性能。

最后你可能会因使用另一个网络服务器而获得一些额外的积分,但不要期望太多。

答案 2 :(得分:0)

我现在处于类似情况,这就是我现在正在实施的方法。您是否考虑过将图像操作推送到客户端?我看到您使用PIL来操作图像,但如果PIL命令不太复杂,您可以在Javascript中重新创建功能吗?使用canvas有很多可能的东西,在我的情况下,我能够在画布toDataURL上用Javascript生成所需的图像,以将其加载到所需的位置。