【问题标题】:Running gevent on apache server + mod_wsgi + bottle在 apache 服务器上运行 gevent + mod_wsgi + bottle
【发布时间】:2013-08-14 11:38:20
【问题描述】:

我读过http://bottlepy.org/docs/dev/tutorial_app.html#server-setup

running Apache + Bottle + Python

Bottle + Apache + WSGI + Sessions

我想知道是否可以在 mod_wsgi 服务器上运行异步 rest api 调用来调用一个不返回任何内容(它的后端逻辑)并且是非阻塞的 py 函数 - 所以我查找了 gevent 但我是还没有找到可以使用 gevents 运行 mod_wsgi 的解决方案。

是否有任何解决方案可以使用 mod_wsgi 或任何其他替代方法在 apache 服务器上运行异步调用?

更新 根据下面安德烈斯的回答;

我用瓶子 + celery 运行了一个简单的 myip 地址返回。所以必须将芹菜作为@celery.task 运行,然后运行(host='localhost', port=8080, debug=True)?是否也需要在终端上启动芹菜工人?在 [runnin local] 之前从未使用过 celery 也可以使用装饰器 @route(/something) 运行瓶子,但 app.route 没有 where app = Bottle() 可能是由于某些 .wsgi 文件错误?

【问题讨论】:

  • 您可以使用 celery,定义您的任务,并从请求处理函数异步运行它们,它不会阻塞,因此处理函数 func 立即返回,但您的客户端应用程序必须定期检查以查看如果有结果。
  • @andrean 如果我必须从客户端应用程序接收请求并在处理后将其存储在数据库中怎么办?但是用户应该继续在他的浏览器上进行通常的交互吗?是不是应该退货?

标签: python-2.7 apache2 celery mod-wsgi bottle


【解决方案1】:

抱歉,评论框放不下。每个请求最终都必须得到响应(或失败/超时)。如果您真的不需要向客户端返回任何数据,只需发送一个带有状态码的空响应即可。如果请求的处理需要时间,它应该异步运行,这就是 celery 的用武之地。所以请求处理程序的阻塞实现:

def request_processor_long_running_blocking_func(request_data):
    # process request data, which takes a lot of time
    # result is probably written into db
    pass

def request_handler_func(request):
    request_processor_long_running_blocking_func(request.data)
    return HttpResponse(status=200)

如果我理解正确,这是您试图避免的,通过使 request_processor_long_running_blocking_func 异步运行,因此 request_handler_func 不会阻塞。这可以用这样的芹菜解决:

from celery.task import task

@task
def request_processor_long_running_blocking_func(request_data):
    # the task decorator wraps your blocking function, with celery's Task class 
    # which has a delay method available for you to call, which will run your function
    # asynchronously on one of your celery background worker processes
    pass

def request_handler_func(request):
    request_processor_long_running_blocking_func.delay(request.data)
    # calling the function with delay won't block, it returns immediately
    # and your response is sent back instantly
    return HttpResponse(status=200)

还有一件事,用ajax发送这些任务请求,这样你的web界面就不会被重新加载或任何东西,所以用户可以在发送请求后继续使用你的应用程序

【讨论】:

  • 还有一件事。这将在 apache 下的 mod_wsgi 上运行,没有像 gevent 需要 run(gevent) 这样的 mod_wsgi apache 不支持的问题?
  • 我正在生产中运行一个由 apache + mod_wsgi 提供的 django 应用程序,它使用 celery 和 django-celery。你需要一个像 RabbitMQ 这样的 celery 消息代理,但这是一个完全外部的服务,如果需要,甚至可以在完全不同的机器上运行。
  • 我用瓶子 + celery 运行了一个简单的 myip 地址返回。所以必须将芹菜作为@celery.task 运行,然后运行(host='localhost', port=8080, debug=True)?是否也需要在终端上启动芹菜工人?在 [runnin local] 之前从未使用过 celery 也可以使用装饰器 @route(/something) 运行瓶子,但 app.route 没有 where app = Bottle() 可能是由于某些 .wsgi 文件错误?
  • 我没有使用瓶子,对此无能为力,但至于 celery worker,是的,你必须启动一个 celery worker 和一个 celery scheduler,这两个进程都是单独的进程,并且你的应用程序是一个单独的过程。 celery 有方便的参数以在守护程序模式下启动它,查看它的文档。有关所有需要的技术的快速教程,hairycode.org/2013/07/23/… 它独立于框架。
最近更新 更多