我正在尝试使用gunicorn及其异步工作者提供长时间运行的请求,但我找不到任何可以开始工作的示例。我使用了示例here,但在返回响应之前进行了调整以添加假延迟(睡眠5秒):
def app(environ, start_response):
data = "Hello, World!\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
time.sleep(5)
return iter([data])
然后我跑了gunicorn所以:
gunicorn -w 4 myapp:app -k gevent
当我打开两个浏览器标签并在其中输入http://127.0.0.1:8000/
并几乎同时发送请求时,请求似乎会被处理顺序 - 一个返回后5秒后,另一个在进一步 5秒后返回。
Q值。我猜测睡眠不是友好的吗?但是有4名工人,所以即使工人的类型是“同步”,两个工人也应该同时处理两个请求?
答案 0 :(得分:6)
我刚刚遇到同样的事情,在这里打开了一个问题:Requests not being distributed across gunicorn workers。结果是,浏览器似乎序列化对同一页面的访问。我猜也许这有可能与可缓存性有关,即浏览器认为页面可以缓存,等到它加载发现它不是因为它发出了另一个请求,所以上。
答案 1 :(得分:1)
当使用非阻塞工作类型的gunicorn时,就像gevent一样,它只会使用一个处理请求的进程,因此你的5秒工作按顺序进行就不足为奇了。
当工作负载很轻,请求率很快时,异步工作程序非常有用,在这种情况下,gunicorn可以利用等待IO浪费的时间(比如,等待套接字可写以写入响应),<通过切换到分配给同一工作人员的另一个请求,通过切换到另一个工作人员来处理另一个请求。。
<强>更新强>
我错了。
当使用非阻塞工作类型的gunicorn时,在gunicorn中使用worker设置,每个worker都是一个进程,它运行一个单独的队列。
因此,如果time.sleep
在不同的进程上运行,它将同时运行,但是当它在同一个工作程序中运行时,它将按顺序执行。
问题是gunicorn负载均衡器可能没有将两个请求分配到两个工作进程中。您可以按os.getpid()
检查当前流程。
答案 2 :(得分:0)
给gevent.sleep
而不是time.sleep
。
-w 4
发生了这种情况很奇怪,但-k gevent
是异步工作者类型,所以可能的gunicorn正在向同一个客户端提供这两个请求。假设发生了什么,time.sleep
将锁定您的流程,除非您使用gevent.monkey.patch_all()
。