多个生产者,单个消费者与Python/mod_wsgi

1 投票
2 回答
583 浏览
提问于 2025-04-15 20:21

我有一个用Pylons框架做的网页应用,它是通过Apache服务器(使用mod_wsgi和prefork模式)来运行的。因为Apache的原因,运行我的应用代码的进程有很多个,它们是同时在工作的。我想把一些不太重要的任务放到后台去处理,这样可以提高“实时”的响应速度。所以我在考虑使用任务队列,很多Apache进程可以把任务添加到这个队列里,然后有一个单独的Python进程来一个一个地处理这些任务,并从队列中移除。

这个队列最好是能保存在硬盘上,这样即使因为停电、服务器重启等原因导致未处理的任务丢失也不会发生。我的问题是,有什么合理的方法来实现这样的队列呢?

关于我尝试过的事情:我一开始用的是简单的SQLite数据库,在里面建了一个表来存储队列项。在进行负载测试时,当并发量增加时,我开始遇到“数据库被锁定”的错误,正如我预料的那样。一个快速且简单的解决办法是把SQLite换成MySQL——它处理并发问题的能力很好,但对我需要做的简单事情来说感觉有点过于复杂。与队列相关的数据库操作在我的性能报告中也显得特别突出。

2 个回答

0

一个网络服务器(任何网络服务器)是一个多生产者、单消费者的过程。

一个简单的解决办法是搭建一个 wsgirefWerkzeug 后端服务器来处理你的后端请求。

因为这个“后端”服务器是用 WSGI 技术构建的,所以它和前端的网络服务器非常相似。唯一的不同是,它不生成 HTML 响应(通常使用 JSON 更简单)。除此之外,其他方面都很直接。

你为这个后端设计 RESTful 交易。你可以使用各种 WSGI 特性来处理 URI 解析、授权、认证等等。一般来说,你不需要会话管理,因为 RESTful 服务器通常不提供会话。

如果你遇到严重的扩展性问题,你可以简单地把你的后端服务器放在 lighttpd 或其他网络引擎上,这样就能创建一个多线程的后端。

1

像Apache的ActiveMQ这样的消息中介非常适合这个场景。

整个流程可以这样理解:

  • 负责处理HTTP请求的应用程序会快速生成回复,并把一些优先级低、比较耗时的任务发送到AMQ队列中。
  • 一个或多个其他进程会订阅这个AMQ队列,来处理这些耗时的任务。

ActiveMQ自带的队列持久化功能很好,因为它会把还没被处理的消息存储在持久化存储中。此外,它的扩展性也很不错,你可以在不同的机器上部署多个HTTP应用、多个消费者应用和AMQ本身。

在我们的项目中,我们使用了类似的方式,项目是用Python写的,底层通信协议使用的是STOMP

撰写回答